[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:
Florent de Labarre
2018-08-28 16:34:55 +02:00
committed by Simon Lejeune
parent c77789b590
commit 3b389348be
3 changed files with 77 additions and 3 deletions
+6
View File
@@ -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
+2 -2
View File
@@ -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'})
+69 -1
View File
@@ -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,
})]})