[FIX] stock, stock_account: return

A return should be valued at the standard price. As the `price_unit`
field is not set as copy=False and a return move is a copy of the
original move, the valuation was wrong.

opw 779803
This commit is contained in:
Simon Lejeune
2017-11-14 17:44:09 +01:00
parent 7a4ab354be
commit a4740861d3
2 changed files with 113 additions and 1 deletions
+1 -1
View File
@@ -108,7 +108,7 @@ class StockMove(models.Model):
"* Done: When the shipment is processed, the state is \'Done\'.")
price_unit = fields.Float(
'Unit Price', help="Technical field used to record the product cost set by the user during a picking confirmation (when costing "
"method used is 'average price' or 'real'). Value given in company currency and in product uom.") # as it's a technical field, we intentionally don't provide the digits attribute
"method used is 'average price' or 'real'). Value given in company currency and in product uom.", copy=False) # as it's a technical field, we intentionally don't provide the digits attribute
backorder_id = fields.Many2one('stock.picking', 'Back Order of', related='picking_id.backorder_id', index=True)
origin = fields.Char("Source Document")
procure_method = fields.Selection([
@@ -1019,6 +1019,118 @@ class TestStockValuation(TransactionCase):
self.assertEqual(move4.remaining_qty, 3.0)
self.assertEqual(move5.remaining_qty, 0.0) # unused in out moves
def test_fifo_perpetual_4(self):
""" Fifo and return handling.
"""
self.product1.cost_method = 'fifo'
# in 8 @ 10
move1 = self.env['stock.move'].create({
'name': 'in 8 @ 10',
'location_id': self.supplier_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 8.0,
'price_unit': 10,
})
move1._action_confirm()
move1._action_assign()
move1.move_line_ids.qty_done = 8.0
move1._action_done()
self.assertEqual(move1.value, 80.0)
self.assertEqual(move1.remaining_value, 80.0)
self.assertEqual(move1.remaining_qty, 8.0)
# in 4 @ 16
move2 = self.env['stock.move'].create({
'name': 'in 4 @ 16',
'location_id': self.supplier_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 4.0,
'price_unit': 16,
})
move2._action_confirm()
move2._action_assign()
move2.move_line_ids.qty_done = 4.0
move2._action_done()
self.assertEqual(move2.value, 64)
self.assertEqual(move2.remaining_value, 64)
self.assertEqual(move2.remaining_qty, 4.0)
# out 10
out_pick = self.env['stock.picking'].create({
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'partner_id': self.env['res.partner'].search([], limit=1).id,
'picking_type_id': self.env.ref('stock.picking_type_out').id,
})
move3 = self.env['stock.move'].create({
'name': 'out 10',
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 10.0,
'picking_id': out_pick.id,
})
move3._action_confirm()
move3._action_assign()
move3.move_line_ids.qty_done = 10.0
move3._action_done()
# note: it' ll have to get 8 units from move1 and 2 from move2
# so its value should be -((8*10) + (2*16)) = -116
self.assertEqual(move3.value, -112.0)
self.assertEqual(move1.remaining_qty, 0)
self.assertEqual(move2.remaining_qty, 2)
self.assertEqual(move3.remaining_qty, 0.0) # unused in out moves
# in 2 @ 6
move4 = self.env['stock.move'].create({
'name': 'in 2 @ 6',
'location_id': self.supplier_location.id,
'location_dest_id': self.stock_location.id,
'product_id': self.product1.id,
'product_uom': self.uom_unit.id,
'product_uom_qty': 2.0,
'price_unit': 6,
})
move4._action_confirm()
move4._action_assign()
move4.move_line_ids.qty_done = 2.0
move4._action_done()
self.assertEqual(move4.value, 12.0)
self.assertEqual(move1.remaining_qty, 0)
self.assertEqual(move2.remaining_qty, 2)
self.assertEqual(move3.remaining_qty, 0.0) # unused in out moves
self.assertEqual(move4.remaining_qty, 2.0)
self.assertEqual(self.product1.standard_price, 16)
# return
stock_return_picking = self.env['stock.return.picking']\
.with_context(active_ids=[out_pick.id], active_id=out_pick.id)\
.create({})
stock_return_picking.product_return_moves.quantity = 1.0 # Return only 2
stock_return_picking_action = stock_return_picking.create_returns()
return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id'])
return_pick.move_lines[0].move_line_ids[0].qty_done = 1.0
return_pick.do_transfer()
self.assertEqual(self.product1.standard_price, 16)
self.assertEqual(return_pick.move_lines.price_unit, 16)
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.