[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

@ -1,2 +1,4 @@
from . import stock_move_line # noqa: F401
from . import stock_backorder_confirmation # noqa: F401
from . import stock_picking # noqa: F401
from . import stock_picking_batch # noqa: F401

View file

@ -0,0 +1,23 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
class StockBackorderConfirmation(models.TransientModel):
_inherit = "stock.backorder.confirmation"
def _check_batch_summary_lines(self):
pickings = self.env["stock.picking"].browse(
self.env.context.get("button_validate_picking_ids", [])
)
for batch in pickings.batch_id:
batch._check_all_products_collected()
def process(self):
self._check_batch_summary_lines()
return super().process()
def process_cancel_backorder(self):
self._check_batch_summary_lines()
return super().process_cancel_backorder()

View file

@ -1,6 +1,7 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api
from odoo import fields
from odoo import models
@ -21,3 +22,18 @@ class StockMoveLine(models.Model):
default=False,
copy=False,
)
consumer_group_id = fields.Many2one(
comodel_name="res.partner",
compute="_compute_consumer_group_id",
readonly=True,
)
@api.depends("picking_id")
def _compute_consumer_group_id(self):
for line in self:
picking = line.picking_id
if picking:
line.consumer_group_id = picking.batch_consumer_group_id
else:
line.consumer_group_id = False

View file

@ -0,0 +1,57 @@
# Copyright 2026 Criptomart
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields
from odoo import models
class StockPicking(models.Model):
_inherit = "stock.picking"
batch_consumer_group_id = fields.Many2one(
comodel_name="res.partner",
compute="_compute_batch_consumer_group_id",
readonly=True,
string="Consumer Group",
)
def _compute_batch_consumer_group_id(self):
for picking in self:
sale = picking.sale_id if "sale_id" in picking._fields else False
if sale and "consumer_group_id" in sale._fields:
picking.batch_consumer_group_id = sale.consumer_group_id
else:
picking.batch_consumer_group_id = False
def _pre_action_done_hook(self):
"""Run collected checks only after Odoo resolves backorders.
This keeps the product summary checkbox informative during the initial
batch validation click, but still enforces it once the user confirms the
actual picking flow that will be processed.
"""
res = super()._pre_action_done_hook()
if res is not True:
return res
self._check_batch_collected_products()
return res
def _check_batch_collected_products(self):
for batch in self.batch_id:
batch_pickings = self.filtered(
lambda picking, batch=batch: picking.batch_id == batch
)
processed_product_ids = (
batch_pickings.move_line_ids.filtered(
lambda line: line.move_id.state not in ("cancel", "done")
and line.product_id
and line.quantity
)
.mapped("product_id")
.ids
)
if not processed_product_ids:
continue
batch._check_all_products_collected(processed_product_ids)

View file

@ -140,11 +140,20 @@ class StockPickingBatch(models.Model):
else:
batch.summary_line_ids = [fields.Command.clear()]
def _check_all_products_collected(self):
"""Ensure all product summary lines are marked as collected before done."""
def _check_all_products_collected(self, product_ids=None):
"""Ensure collected is checked for processed products only.
The product summary remains informative until Odoo knows which products
are actually being validated after the backorder decision.
"""
for batch in self:
not_collected_lines = batch.summary_line_ids.filtered(
lambda line: not line.is_collected
lambda line: (
line.qty_done > 0
and not line.is_collected
and (not product_ids or line.product_id.id in product_ids)
)
)
if not not_collected_lines:
continue
@ -161,10 +170,6 @@ class StockPickingBatch(models.Model):
)
raise UserError(message)
def action_done(self):
self._check_all_products_collected()
return super().action_done()
class StockPickingBatchSummaryLine(models.Model):
_name = "stock.picking.batch.summary.line"