[FIX] stock: receive products with detailed operations
A recursion error may appear when a user receives a product. To reproduce the issue: 1. Create a tracked-by-usn product P 2. Create an immediate receipt for P 3. In the Detailed Operations wizard, add a line and Confirm Error: An Odoo Server Error is raised (`RecursionError`) [1] When confirming the wizard, a new SML is created. In the creation method, we define the `product_uom_qty` of the associated SM: https://github.com/odoo/odoo/blob/1b1b320c4b8a0c08d156e569216cbea1100fb1bb/addons/stock/models/stock_move_line.py#L294 [2] In the writing method of the SM, because we are defining `product_uom_qty`, we unreserve and assign again the SM: https://github.com/odoo/odoo/blob/1b1b320c4b8a0c08d156e569216cbea1100fb1bb/addons/stock/models/stock_move.py#L606-L607 [3] In the assigning method, because there isn't any need, it quickly lead to https://github.com/odoo/odoo/blob/1b1b320c4b8a0c08d156e569216cbea1100fb1bb/addons/stock/models/stock_move.py#L1487-L1488 i.e., the SM is considered as assigned and flagged to be redirected [4] In the redirection method (`_apply_putaway_strategy`), we define the new destination location of the SML. https://github.com/odoo/odoo/blob/1b1b320c4b8a0c08d156e569216cbea1100fb1bb/addons/stock/models/stock_move_line.py#L230 [5] Because of this, in the writing method of the SML, we define again the `product_uom_qty` of the SM: https://github.com/odoo/odoo/blob/1b1b320c4b8a0c08d156e569216cbea1100fb1bb/addons/stock/models/stock_move_line.py#L461-L462 This brings us back to step 2 => Recursion In the writing method of the SM (step 2), we can prevent the "unreserve & reserve again" step thanks to a key-context: `do_not_unreserve`. OPW-2833951 closes odoo/odoo#90171 X-original-commit: fbc5cf7813c2e9d8a02fe8a73a74bfa32a8f9b96 Signed-off-by: William Henrotin (whe) <whe@odoo.com> Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
@@ -208,6 +208,7 @@ class StockMoveLine(models.Model):
|
||||
packaging=self.move_id.product_packaging_id)
|
||||
|
||||
def _apply_putaway_strategy(self):
|
||||
self = self.with_context(do_not_unreserve=True)
|
||||
for package, smls in groupby(self, lambda sml: sml.result_package_id):
|
||||
smls = self.env['stock.move.line'].concat(*smls)
|
||||
excluded_smls = smls
|
||||
|
||||
@@ -2220,3 +2220,25 @@ class TestStockFlow(TestStockCommon):
|
||||
self.assertEqual(picking.state, 'cancel')
|
||||
self.assertEqual(move.state, 'cancel')
|
||||
self.assertEqual(scrap.move_id.state, 'done')
|
||||
|
||||
def test_receive_tracked_product(self):
|
||||
self.productA.tracking = 'serial'
|
||||
type_in = self.env['stock.picking.type'].browse(self.picking_type_in)
|
||||
|
||||
receipt_form = Form(self.env['stock.picking'].with_context(default_immediate_transfer=True))
|
||||
receipt_form.picking_type_id = type_in
|
||||
with receipt_form.move_ids_without_package.new() as move_line:
|
||||
move_line.product_id = self.productA
|
||||
receipt = receipt_form.save()
|
||||
|
||||
move_form = Form(receipt.move_ids, view='stock.view_stock_move_nosuggest_operations')
|
||||
with move_form.move_line_nosuggest_ids.new() as line:
|
||||
line.lot_name = "USN01"
|
||||
move_form.save()
|
||||
|
||||
receipt.button_validate()
|
||||
quant = self.productA.stock_quant_ids.filtered(lambda q: q.location_id.id == self.stock_location)
|
||||
|
||||
self.assertEqual(receipt.state, 'done')
|
||||
self.assertEqual(quant.quantity, 1.0)
|
||||
self.assertEqual(quant.lot_id.name, 'USN01')
|
||||
|
||||
Reference in New Issue
Block a user