[FIX] stock_account: valuation change has always positive value

Steps to reproduce:
1. Create a new product with a cost of 10 (std, manual)
2. Create an inventory adjustment to set the quantity to -3
3. Change the product's category to real-time

Now the valuation for this product is -30€ but the accounting part
has 30€, creating a difference of 60€.

Before this commit:
Changing the valuation to real-time while having a negative
quantity/value gives a positive value in accounting.

After this commit:
Changing the valuation to real-time while having a negative
quantity/value gives a negative value in accounting.

opw-3390692

closes odoo/odoo#143000

X-original-commit: 9a0e620d2fa1d5e55d73bc4920f26ef2ba82ce9d
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Walravens Mathieu (wama) <wama@odoo.com>
This commit is contained in:
Mathieu Walravens
2023-11-22 00:46:23 +00:00
parent 453fe870c1
commit c49ac84fb8
2 changed files with 41 additions and 0 deletions
+5
View File
@@ -648,6 +648,11 @@ class ProductProduct(models.Model):
debit_account_id = product_accounts[product.id]['stock_valuation'].id
credit_account_id = product_accounts[product.id]['stock_input'].id
value = out_stock_valuation_layer.value
if out_stock_valuation_layer.currency_id.compare_amounts(value, 0) < 0:
# Swap accounts makes a negative value in accounting
debit_account_id = product_accounts[product.id]['stock_output'].id
credit_account_id = product_accounts[product.id]['stock_valuation'].id
move_vals = {
'journal_id': product_accounts[product.id]['stock_journal'].id,
'company_id': self.env.company.id,
@@ -939,6 +939,12 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
'property_stock_journal': cls.stock_journal.id,
})
def _get_stock_account_balance(self, stock_valuation_layer):
"""Return the accounting balance from the stock valuation account for the given SVL"""
stock_valuation_account = stock_valuation_layer.product_id.categ_id.property_stock_valuation_account_id
return stock_valuation_layer.account_move_id.line_ids.filtered(lambda line: line.account_id == stock_valuation_account).balance
def test_standard_manual_to_auto_1(self):
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_valuation = 'manual_periodic'
@@ -962,6 +968,9 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
# An accounting entry should only be created for the replenish now that the category is perpetual.
self.assertEqual(len(self.product1.stock_valuation_layer_ids.mapped('account_move_id')), 1)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 3)
# Check the entry's value
last_svl = self.product1.stock_valuation_layer_ids.sorted()[-1]
self.assertEqual(self._get_stock_account_balance(last_svl), self.product1.value_svl)
for svl in self.product1.stock_valuation_layer_ids.sorted()[-2:]:
self.assertEqual(svl.description, 'Valuation method change for product category All: from manual_periodic to real_time.')
@@ -996,6 +1005,33 @@ class TestStockValuationChangeValuation(TestStockValuationCommon):
# An accounting entry should only be created for the replenish now that the category is perpetual.
self.assertEqual(len(self.product1.stock_valuation_layer_ids.mapped('account_move_id')), 1)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 3)
# Check the entry's value
last_svl = self.product1.stock_valuation_layer_ids.sorted()[-1]
self.assertEqual(self._get_stock_account_balance(last_svl), self.product1.value_svl)
def test_standard_manual_to_auto_3(self):
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_valuation = 'manual_periodic'
self.product1.product_tmpl_id.standard_price = 10
self._make_out_move(self.product1, 10, force_assign=True)
self.assertEqual(self.product1.value_svl, -100)
self.assertEqual(self.product1.quantity_svl, -10)
self.assertEqual(len(self.product1.stock_valuation_layer_ids.account_move_id), 0)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 1)
self.product1.product_tmpl_id.categ_id.property_valuation = 'real_time'
self.assertEqual(self.product1.value_svl, -100)
self.assertEqual(self.product1.quantity_svl, -10)
# An accounting entry should only be created for the replenish now that the category is perpetual.
self.assertEqual(len(self.product1.stock_valuation_layer_ids.account_move_id), 1)
self.assertEqual(len(self.product1.stock_valuation_layer_ids), 3)
# Check the entry's value
last_svl = self.product1.stock_valuation_layer_ids.sorted()[-1]
self.assertEqual(self._get_stock_account_balance(last_svl), self.product1.value_svl)
for svl in self.product1.stock_valuation_layer_ids.sorted()[-2:]:
self.assertEqual(svl.description, 'Valuation method change for product category All: from manual_periodic to real_time.')
def test_standard_auto_to_manual_1(self):
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'