summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Lejeune <sle@openerp.com>2020-02-03 13:58:37 +0000
committerSimon Lejeune <sle@openerp.com>2020-02-06 17:15:18 +0000
commitde26f4a4e8d7226bee66a14a787f4890224f6e22 (patch)
treebdb5bac1ca06e8f7a79008013815dd2e4c3f570c
parent5e2c71b6e7186801814474a8705a3d90e70c749b (diff)
[FIX] stock_account: anglo saxon and corrections
Don't ignore correction layers when computing the anglo saxon price unit. We use the `stock_valuation_layer_id` field on the layer to point the correction layer to the corrected layer. When computing the average price of the delivered things, ignore correction entry but take them into account when choosing a corrected entry. opw-2179900 closes odoo/odoo#44774 X-original-commit: 3831649b81c1271977730cdf46100f814687af61 Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
-rw-r--r--addons/sale_stock/tests/test_anglo_saxon_valuation.py76
-rw-r--r--addons/stock_account/models/product.py6
2 files changed, 81 insertions, 1 deletions
diff --git a/addons/sale_stock/tests/test_anglo_saxon_valuation.py b/addons/sale_stock/tests/test_anglo_saxon_valuation.py
index 1cff7c4e7bb..ba0c78ca14e 100644
--- a/addons/sale_stock/tests/test_anglo_saxon_valuation.py
+++ b/addons/sale_stock/tests/test_anglo_saxon_valuation.py
@@ -855,3 +855,79 @@ class TestAngloSaxonValuation(SavepointCase):
self.assertEqual(income_aml.debit, 0)
self.assertEqual(income_aml.credit, 24)
+ def test_fifo_delivered_invoice_post_delivery_2(self):
+ """Receive at 8 then at 10. Sale order 10@12 and deliver without receiving the 2 missing.
+ receive 2@12. Invoice."""
+ self.product.categ_id.property_cost_method = 'fifo'
+ self.product.invoice_policy = 'delivery'
+ self.product.standard_price = 10
+
+ in_move_1 = self.env['stock.move'].create({
+ 'name': 'a',
+ 'product_id': self.product.id,
+ 'location_id': self.env.ref('stock.stock_location_suppliers').id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_uom': self.product.uom_id.id,
+ 'product_uom_qty': 8,
+ 'price_unit': 10,
+ })
+ in_move_1._action_confirm()
+ in_move_1.quantity_done = 8
+ in_move_1._action_done()
+
+ # Create and confirm a sale order for 2@12
+ sale_order = self.env['sale.order'].create({
+ 'partner_id': self.customer.id,
+ 'order_line': [
+ (0, 0, {
+ 'name': self.product.name,
+ 'product_id': self.product.id,
+ 'product_uom_qty': 10.0,
+ 'product_uom': self.product.uom_id.id,
+ 'price_unit': 12,
+ 'tax_id': False, # no love taxes amls
+ })],
+ })
+ sale_order.action_confirm()
+
+ # Deliver 10
+ sale_order.picking_ids.move_lines.quantity_done = 10
+ sale_order.picking_ids.button_validate()
+
+ # Make the second receipt
+ in_move_2 = self.env['stock.move'].create({
+ 'name': 'a',
+ 'product_id': self.product.id,
+ 'location_id': self.env.ref('stock.stock_location_suppliers').id,
+ 'location_dest_id': self.stock_location.id,
+ 'product_uom': self.product.uom_id.id,
+ 'product_uom_qty': 2,
+ 'price_unit': 12,
+ })
+ in_move_2._action_confirm()
+ in_move_2.quantity_done = 2
+ in_move_2._action_done()
+ self.assertEqual(self.product.stock_valuation_layer_ids[-1].value, -4) # we sent two at 10 but they should have been sent at 12
+ self.assertEqual(self.product.stock_valuation_layer_ids[-1].quantity, 0)
+ self.assertEqual(sale_order.order_line.move_ids.stock_valuation_layer_ids[-1].quantity, 0)
+
+ # Invoice the sale order.
+ invoice = sale_order._create_invoices()
+ invoice.post()
+
+ # Check the resulting accounting entries
+ amls = invoice.line_ids
+ self.assertEqual(len(amls), 4)
+ stock_out_aml = amls.filtered(lambda aml: aml.account_id == self.stock_output_account)
+ self.assertEqual(stock_out_aml.debit, 0)
+ self.assertEqual(stock_out_aml.credit, 104)
+ cogs_aml = amls.filtered(lambda aml: aml.account_id == self.expense_account)
+ self.assertEqual(cogs_aml.debit, 104)
+ self.assertEqual(cogs_aml.credit, 0)
+ receivable_aml = amls.filtered(lambda aml: aml.account_id == self.recv_account)
+ self.assertEqual(receivable_aml.debit, 120)
+ self.assertEqual(receivable_aml.credit, 0)
+ income_aml = amls.filtered(lambda aml: aml.account_id == self.income_account)
+ self.assertEqual(income_aml.debit, 0)
+ self.assertEqual(income_aml.credit, 120)
+
diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py
index b6ce7a66615..3d72df9e207 100644
--- a/addons/stock_account/models/product.py
+++ b/addons/stock_account/models/product.py
@@ -395,6 +395,7 @@ class ProductProduct(models.Model):
'stock_move_id': move.id,
'company_id': move.company_id.id,
'description': 'Revaluation of %s (negative inventory)' % move.picking_id.name or move.name,
+ 'stock_valuation_layer_id': svl_to_vacuum.id,
}
vacuum_svl = self.env['stock.valuation.layer'].sudo().create(vals)
@@ -616,6 +617,8 @@ class ProductProduct(models.Model):
tmp_value = 0 # to accumulate the value taken on the candidates
for candidate in candidates:
candidate_quantity = abs(candidate.quantity)
+ if float_is_zero(candidate_quantity, precision_rounding=candidate.uom_id.rounding):
+ continue # correction entries
if not float_is_zero(qty_invoiced, precision_rounding=candidate.uom_id.rounding):
qty_ignored = min(qty_invoiced, candidate_quantity)
qty_invoiced -= qty_ignored
@@ -625,7 +628,8 @@ class ProductProduct(models.Model):
qty_taken_on_candidate = min(qty_to_take_on_candidates, candidate_quantity)
qty_to_take_on_candidates -= qty_taken_on_candidate
- tmp_value += qty_taken_on_candidate * (candidate.value / candidate.quantity)
+ tmp_value += qty_taken_on_candidate * \
+ ((candidate.value + sum(candidate.stock_valuation_layer_ids.mapped('value'))) / candidate.quantity)
if float_is_zero(qty_to_take_on_candidates, precision_rounding=candidate.uom_id.rounding):
break