Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions addons/stock_account/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,8 @@ def _run_fifo_get_stack(self, lot=None, at_date=None, location=None):
if lot:
fifo_stack_size = lot.product_qty
else:
fifo_stack_size = int(self._with_valuation_context().with_context(to_date=at_date).qty_available)
if fifo_stack_size <= 0:
fifo_stack_size = self._with_valuation_context().with_context(to_date=at_date).qty_available
if self.uom_id.compare(fifo_stack_size, 0) <= 0:
return fifo_stack, 0

moves_domain = Domain([
Expand All @@ -412,24 +412,21 @@ def _run_fifo_get_stack(self, lot=None, at_date=None, location=None):
else:
moves_domain &= Domain([('is_in', '=', True)])

# Base limit to 100 to avoid issue with other UoM than Unit
initial_limit = fifo_stack_size * 10
unit_uom = self.env.ref('uom.product_uom_unit', raise_if_not_found=False)
if unit_uom and self.uom_id != unit_uom:
initial_limit = max(initial_limit, 100)
# Arbitrary limit as we can't guess how many moves correspond to the qty_available, but avoid fetching all moves at the same time.
initial_limit = 100
moves_in = self.env['stock.move'].search(moves_domain, order='date desc, id desc', limit=initial_limit)

remaining_qty_on_first_stack_move = 0
current_offset = 0
# Go to the bottom of the stack
while fifo_stack_size > 0 and moves_in:
while self.uom_id.compare(fifo_stack_size, 0) > 0 and moves_in:
move = moves_in[0]
moves_in = moves_in[1:]
in_qty = move._get_valued_qty()
fifo_stack.append(move)
remaining_qty_on_first_stack_move = min(in_qty, fifo_stack_size)
fifo_stack_size -= in_qty
if fifo_stack_size > 0 and not moves_in:
if self.uom_id.compare(fifo_stack_size, 0) > 0 and not moves_in:
# We need to fetch more moves
current_offset += 1
moves_in = self.env['stock.move'].search(moves_domain, order='date desc, id desc', offset=current_offset * initial_limit, limit=initial_limit)
Expand Down
10 changes: 10 additions & 0 deletions addons/stock_account/tests/test_stockvaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,16 @@ def test_fifo_perpetual_2(self):
self.assertEqual(move8.remaining_qty, 0.0) # unused in internal moves
self.assertEqual(move9.remaining_qty, 0.0) # unused in out moves

def test_fifo_perpetual_3(self):
""" Make sure that the fifo valuation is correct for non-integer quantities.
"""
product = self.product_fifo

move1 = self._make_in_move(product, 1.9, 10)

self.assertAlmostEqual(move1.remaining_qty, 1.9)
self.assertAlmostEqual(move1.remaining_value, 19)

def test_fifo_negative_1(self):
""" Send products that you do not have. Value the first outgoing move to the standard
price, receive in multiple times the delivered quantity and run _fifo_vacuum to compensate.
Expand Down