[FIX] stock: move line: lot and product
In the detailed operations view and in an immediate transfer:
- add a line
- select a random lot_id
- select a random product_id
- validate
The system won't raise while the combination of product_id/lot_id may
not make sense. We add a constraint to solve this isse.
Closes #25766
opw-1868453
This commit is contained in:
committed by
Simon Lejeune
parent
c77789b590
commit
3b389348be
@@ -67,6 +67,12 @@ class StockMoveLine(models.Model):
|
||||
def _compute_product_qty(self):
|
||||
self.product_qty = self.product_uom_id._compute_quantity(self.product_uom_qty, self.product_id.uom_id, rounding_method='HALF-UP')
|
||||
|
||||
@api.constrains('lot_id', 'product_id')
|
||||
def _check_lot_product(self):
|
||||
for line in self:
|
||||
if line.lot_id and line.product_id != line.lot_id.product_id:
|
||||
raise ValidationError(_('This lot %s is incompatible with this product %s' % (line.lot_id.name, line.product_id.display_name)))
|
||||
|
||||
@api.one
|
||||
def _set_product_qty(self):
|
||||
""" The meaning of product_qty field changed lately and is now a functional field computing the quantity
|
||||
|
||||
@@ -2997,11 +2997,11 @@ class StockMove(TransactionCase):
|
||||
"""
|
||||
lot1 = self.env['stock.production.lot'].create({
|
||||
'name': 'lot1',
|
||||
'product_id': self.product1.id,
|
||||
'product_id': self.product3.id,
|
||||
})
|
||||
lot2 = self.env['stock.production.lot'].create({
|
||||
'name': 'lot2',
|
||||
'product_id': self.product1.id,
|
||||
'product_id': self.product3.id,
|
||||
})
|
||||
package1 = self.env['stock.quant.package'].create({'name': 'test_edit_reserved_move_line_5'})
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@@ -145,3 +145,71 @@ class TestRobustness(TransactionCase):
|
||||
self.assertEqual(len(self.env['stock.quant']._gather(self.product1, self.stock_location, package_id=package)), 0)
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._gather(self.product1, self.stock_location).reserved_quantity, 0)
|
||||
|
||||
def test_lot_id_product_id_mix(self):
|
||||
""" Make sure it isn't possible to create a move line with a lot incompatible with its
|
||||
product.
|
||||
"""
|
||||
product1 = self.env['product.product'].create({
|
||||
'name': 'Product 1',
|
||||
'type': 'product',
|
||||
'categ_id': self.env.ref('product.product_category_all').id,
|
||||
'tracking': 'lot',
|
||||
})
|
||||
product2 = self.env['product.product'].create({
|
||||
'name': 'Product 2',
|
||||
'type': 'product',
|
||||
'categ_id': self.env.ref('product.product_category_all').id,
|
||||
'tracking': 'lot',
|
||||
})
|
||||
|
||||
lot1 = self.env['stock.production.lot'].create({
|
||||
'name': 'lot1',
|
||||
'product_id': product1.id,
|
||||
})
|
||||
lot2 = self.env['stock.production.lot'].create({
|
||||
'name': 'lot2',
|
||||
'product_id': product2.id,
|
||||
})
|
||||
|
||||
self.env['stock.quant']._update_available_quantity(product1, self.stock_location, 1, lot_id=lot1)
|
||||
self.env['stock.quant']._update_available_quantity(product2, self.stock_location, 1, lot_id=lot2)
|
||||
|
||||
move1 = self.env['stock.move'].create({
|
||||
'name': 'test_lot_id_product_id_mix_move_1',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
move2 = self.env['stock.move'].create({
|
||||
'name': 'test_lot_id_product_id_mix_move_2',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': product2.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 1.0,
|
||||
})
|
||||
(move1 + move2)._action_confirm()
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
move1.write({'move_line_ids': [(0, 0, {
|
||||
'product_id': product1.id,
|
||||
'product_uom_id': self.uom_unit.id,
|
||||
'qty_done': 1,
|
||||
'lot_id': lot2.id,
|
||||
'location_id': move1.location_id.id,
|
||||
'location_dest_id': move1.location_dest_id.id,
|
||||
})]})
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
move2.write({'move_line_ids': [(0, 0, {
|
||||
'product_id': product2.id,
|
||||
'product_uom_id': self.uom_unit.id,
|
||||
'qty_done': 1,
|
||||
'lot_id': lot1.id,
|
||||
'location_id': move2.location_id.id,
|
||||
'location_dest_id': move2.location_dest_id.id,
|
||||
})]})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user