[FIX] purchase_stock, stock_landed_costs: bill after LC

1. Create a product with a category AVCO + Automated and set a price
   difference account
2. Create a Purchase Order for 1 unit at a value of 1000,
3. Stock entry at receipt
                               D         C
   Stock interim received             1000
   Stock valuation          1000
4. Create a vendor bill for a Landed cost, post it
                               D         C
   Stock interim received    100
5. Create the landed cost from the bill and apply it on the receipt of
   point 3
                               D         C
   Stock valuation           100
   Stock interim received              100
6. Create the vendor bill for the initial PO

Current entry is not correct:
                               D         C
Stock interim received      1000
Price difference account               100  --> Shouldn't take place
Stock interim received       100            --> Shouldn't take place

This happens because the valuation layers of the landed cost are taken
into account when computing the unit price of the product.

This shouldn't be the case: when computing the price difference between
the invoice price and the stock move price, LC should be filtered out.

opw-2183511

closes odoo/odoo#47804

X-original-commit: 9bd3feb7f8778ba65e1974ef012ca3a4608878b1
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
This commit is contained in:
Nicolas Martinelli
2020-03-23 08:08:01 +00:00
parent c71658bb8c
commit c0ccf6f103
2 changed files with 74 additions and 2 deletions
@@ -74,8 +74,9 @@ class AccountMove(models.Model):
# In case val_stock_move is a return move, its valuation entries have been made with the
# currency rate corresponding to the original stock move
valuation_date = val_stock_move.origin_returned_move_id.date or val_stock_move.date
layers_qty = sum(val_stock_move.mapped('stock_valuation_layer_ids.quantity'))
layers_values = sum(val_stock_move.mapped('stock_valuation_layer_ids.value'))
svl = val_stock_move.mapped('stock_valuation_layer_ids').filtered(lambda l: l.quantity)
layers_qty = sum(svl.mapped('quantity'))
layers_values = sum(svl.mapped('value'))
valuation_price_unit_total += line.company_currency_id._convert(
layers_values, move.currency_id,
move.company_id, valuation_date, round=False,
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import unittest
from odoo.addons.stock_landed_costs.tests.common import TestStockLandedCostsCommon
from odoo.addons.stock_landed_costs.tests.test_stockvaluationlayer import TestStockValuationLCCommon
from odoo.addons.stock_account.tests.test_stockvaluation import _create_accounting_data
from odoo.tests import tagged, Form
@@ -300,3 +301,73 @@ class TestLandedCosts(TestStockLandedCostsCommon):
def _error_message(self, actucal_cost, computed_cost):
return 'Additional Landed Cost should be %s instead of %s' % (actucal_cost, computed_cost)
@tagged('post_install', '-at_install')
class TestLandedCostsWithPurchaseAndInv(TestStockValuationLCCommon):
def test_invoice_after_lc(self):
self.env.company.anglo_saxon_accounting = True
self.product1.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_valuation = 'real_time'
self.product1.product_tmpl_id.invoice_policy = 'delivery'
self.price_diff_account = self.env['account.account'].create({
'name': 'price diff account',
'code': 'price diff account',
'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
})
self.product1.property_account_creditor_price_difference = self.price_diff_account
# Create PO
po_form = Form(self.env['purchase.order'])
po_form.partner_id = self.env['res.partner'].create({'name': 'vendor'})
with po_form.order_line.new() as po_line:
po_line.product_id = self.product1
po_line.product_qty = 1
po_line.price_unit = 455.0
order = po_form.save()
order.button_confirm()
# Receive the goods
receipt = order.picking_ids[0]
receipt.move_lines.quantity_done = 1
receipt.button_validate()
# Check SVL and AML
svl = self.env['stock.valuation.layer'].search([('stock_move_id', '=', receipt.move_lines.id)])
self.assertAlmostEqual(svl.value, 455)
aml = self.env['account.move.line'].search([('account_id', '=', self.stock_valuation_account.id)])
self.assertAlmostEqual(aml.debit, 455)
# Create and validate LC
lc = self.env['stock.landed.cost'].create(dict(
picking_ids=[(6, 0, [receipt.id])],
account_journal_id=self.stock_journal.id,
cost_lines=[
(0, 0, {
'name': 'equal split',
'split_method': 'equal',
'price_unit': 99,
'product_id': self.productlc1.id,
}),
],
))
lc.compute_landed_cost()
lc.button_validate()
# Check LC, SVL and AML
self.assertAlmostEqual(lc.valuation_adjustment_lines.final_cost, 554)
svl = self.env['stock.valuation.layer'].search([('stock_move_id', '=', receipt.move_lines.id)], order='id desc', limit=1)
self.assertAlmostEqual(svl.value, 99)
aml = self.env['account.move.line'].search([('account_id', '=', self.stock_valuation_account.id)], order='id desc', limit=1)
self.assertAlmostEqual(aml.debit, 99)
# Create an invoice with the same price
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
move_form.partner_id = order.partner_id
move_form.purchase_id = order
move = move_form.save()
move.post()
# Check nothing was posted in the price difference account
price_diff_aml = self.env['account.move.line'].search([('account_id','=', self.price_diff_account.id), ('move_id', '=', move.id)])
self.assertEqual(len(price_diff_aml), 0, "No line should have been generated in the price difference account.")