[FIX] stock: don't create empty move lines for receipts

When creating a receipt with products tracked by lot or serial number,
empty move lines are automatically created when the receipt is validated

Steps to reproduce:
1. Install Inventory
2. Go to Inventory > Configuration > Warehouse Management > Operations
   Types
3. Open Receipts and enable 'Show Detailed Operations' and 'Pre-fill
   Detailed Operations'
4. Go to Overview > Receipts and create a new receipt, in Detailed
   Operations add product 'Cable Management Box' with any serial number
   and a quantity of 1
5. Validate the receipt, a new line is added in Detailed Operations with
   quantity 0

Solution:
When we create a stock move line and we need to create a lot, we create
the lot with the context key `do_not_unreserve`

Problem:
When we create and write the lot on stock move lines, we detect that the
`product_uom_qty` is not set. Because we are in an immediate transfer,
we will try and assign it the `quantity_done`.
https://github.com/odoo/odoo/blob/7fec535f3d84d15899aea5e61b51947f260d9697/addons/stock/models/stock_move_line.py#L467-L469
By writing the `product_uom_qty` on the stock move, we will try to
unreserve and reserve again the stock move (if `do_not_unreserve` is not
in the context)
https://github.com/odoo/odoo/blob/ba3bb9b701a382c4052ddb57392baeee32625937/addons/stock/models/stock_move.py#L569-L576
This will then create the undesired empty move lines (that are supposed
to be the 'Pre-filled Detailed Operations') in _action_assign
https://github.com/odoo/odoo/blob/3e8a45fce0af0aa5792f0aea978d4ab78ab50a40/addons/stock/models/stock_move.py#L1586

opw-2897875

closes odoo/odoo#95983

Signed-off-by: Tiffany Chang <tic@odoo.com>
This commit is contained in:
MerlinGuillaume
2022-08-11 11:00:46 +02:00
parent 61b0de8b3f
commit 6c853953eb
2 changed files with 21 additions and 1 deletions
+1 -1
View File
@@ -566,7 +566,7 @@ class StockMoveLine(models.Model):
raise UserError(_('You need to supply a Lot/Serial Number for product: \n - ') +
'\n - '.join(mls_tracked_without_lot.mapped('product_id.display_name')))
ml_to_create_lot = self.env['stock.move.line'].browse(ml_ids_to_create_lot)
ml_to_create_lot._create_and_assign_production_lot()
ml_to_create_lot.with_context(do_not_unreserve=True)._create_and_assign_production_lot()
mls_to_delete = self.env['stock.move.line'].browse(ml_ids_to_delete)
mls_to_delete.unlink()
+20
View File
@@ -2232,6 +2232,26 @@ class TestSinglePicking(TestStockCommon):
self.assertEqual(picking.move_ids.state, 'cancel', "Stock move should be in a cancel state.")
self.assertEqual(picking.state, 'cancel', "Picking should be in a cancel state.")
def test_immediate_picking_with_lot(self):
self.productA.tracking = 'serial'
picking = self.env['stock.picking'].create({
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'picking_type_id': self.picking_type_in,
'immediate_transfer': True,
'move_line_ids': [(0, 0, {
'product_id': self.productA.id,
'product_uom_id': self.productA.uom_id.id,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'qty_done': 1,
'lot_name': '12345',
})]
})
self.assertEqual(len(picking.move_line_ids), 1, "Picking should have a single move line")
picking.button_validate()
self.assertEqual(len(picking.move_line_ids), 1, "Picking should have a single move line")
class TestStockUOM(TestStockCommon):
@classmethod