From eac433de8b5ce87b24ec05cf98f9579ae13b53f8 Mon Sep 17 00:00:00 2001 From: mafo-odoo Date: Thu, 18 Aug 2022 10:54:45 +0000 Subject: [PATCH] [FIX] stock_account, purchase_stock: no stock account in manual valuation Issues: 1) When the inventory valuation is Manual the stock accounts field of the product category should be empty and they should be set when the inventory valuation is Automated. 2) For the moment at installation all the categories have the Manual default value and the comapy account default values for the stock accounts (not respecting condition 1) Solutions: For issue 1 we add checks on the write and create functions of the product category model so that after creation/modification the instance respect the condition For issue 2 we add at the end of the post_hook script some code to set an empty stock account property for every product category. opw-2746384 closes odoo/odoo#110715 X-original-commit: aa744f1172012d3d74c12bb73e06265d6e64c6e1 Signed-off-by: William Henrotin (whe) --- .../tests/test_stockvaluation.py | 9 +++-- addons/stock_account/__init__.py | 21 +++++++----- addons/stock_account/models/product.py | 33 ++++++++++++++++++- .../test_stock_valuation_layer_revaluation.py | 1 + .../tests/test_stockvaluationlayer.py | 5 +++ 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/addons/purchase_stock/tests/test_stockvaluation.py b/addons/purchase_stock/tests/test_stockvaluation.py index d53f57d554e..d6d10d7efef 100644 --- a/addons/purchase_stock/tests/test_stockvaluation.py +++ b/addons/purchase_stock/tests/test_stockvaluation.py @@ -55,11 +55,13 @@ class TestStockValuation(TransactionCase): 'type': 'general', }) cls.product1.categ_id.write({ + 'property_valuation': 'real_time', 'property_stock_account_input_categ_id': cls.stock_input_account.id, 'property_stock_account_output_categ_id': cls.stock_output_account.id, 'property_stock_valuation_account_id': cls.stock_valuation_account.id, 'property_stock_journal': cls.stock_journal.id, }) + cls.env.ref('base.EUR').active = True def test_change_unit_cost_average_1(self): """ Confirm a purchase order and create the associated receipt, change the unit cost of the @@ -285,7 +287,8 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon): 'property_stock_account_output_categ_id': cls.stock_output_account.id, 'property_stock_valuation_account_id': cls.stock_valuation_account.id, 'property_stock_journal': cls.stock_journal.id, - 'property_account_creditor_price_difference_categ': cls.product1.product_tmpl_id.get_product_accounts()['expense'] + 'property_account_creditor_price_difference_categ': cls.product1.product_tmpl_id.get_product_accounts()['expense'], + 'property_valuation': 'real_time', }) def test_change_currency_rate_average_1(self): @@ -791,14 +794,14 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon): inv.action_post() move_lines = inv.line_ids - self.assertEqual(len(move_lines), 2) + self.assertEqual(len(move_lines), 4) payable_line = move_lines.filtered(lambda l: l.account_id.account_type == 'liability_payable') self.assertEqual(payable_line.amount_currency, -100.0) self.assertAlmostEqual(payable_line.balance, -66.67) - stock_line = move_lines.filtered(lambda l: l.account_id == self.stock_input_account) + stock_line = move_lines.filtered(lambda l: l.account_id == self.stock_input_account and l.balance > 0) self.assertEqual(stock_line.amount_currency, 100.0) self.assertAlmostEqual(stock_line.balance, 66.67) diff --git a/addons/stock_account/__init__.py b/addons/stock_account/__init__.py index fd3f4a2eddb..99d699ac408 100644 --- a/addons/stock_account/__init__.py +++ b/addons/stock_account/__init__.py @@ -14,7 +14,12 @@ def _configure_journals(cr, registry): # if we already have a coa installed, create journal and set property field company_ids = env['res.company'].search([('chart_template_id', '!=', False)]) - + todo_list = [ + 'property_stock_account_input_categ_id', + 'property_stock_account_output_categ_id', + 'property_stock_valuation_account_id', + ] + # Property Stock Accounts for company_id in company_ids: # Check if property exists for stock account journal exists field = env['ir.model.fields']._get("product.category", "property_stock_journal") @@ -43,13 +48,6 @@ def _configure_journals(cr, registry): company_id, ) - # Property Stock Accounts - todo_list = [ - 'property_stock_account_input_categ_id', - 'property_stock_account_output_categ_id', - 'property_stock_valuation_account_id', - ] - for name in todo_list: account = getattr(company_id, name) if account: @@ -59,3 +57,10 @@ def _configure_journals(cr, registry): account, company_id, ) + for name in todo_list: + env['ir.property']._set_multi( + name, + 'product.category', + {category.id: False for category in env['product.category'].search([])}, + True + ) diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py index 34b65d0bc16..ef2e0044b77 100644 --- a/addons/stock_account/models/product.py +++ b/addons/stock_account/models/product.py @@ -804,8 +804,23 @@ class ProductCategory(models.Model): new_cost_method = vals.get('property_cost_method') new_valuation = vals.get('property_valuation') - for product_category in self: + property_stock_fields = ['property_stock_account_input_categ_id', 'property_stock_account_output_categ_id', 'property_stock_valuation_account_id'] + if 'property_valuation' in vals and vals['property_valuation'] == 'manual_periodic' and product_category.property_valuation != 'manual_periodic': + for stock_property in property_stock_fields: + vals[stock_property] = False + elif 'property_valuation' in vals and vals['property_valuation'] == 'real_time' and product_category.property_valuation != 'real_time': + company_id = self.env.company + for stock_property in property_stock_fields: + vals[stock_property] = vals.get(stock_property, False) or company_id[stock_property] + elif product_category.property_valuation == 'manual_periodic': + for stock_property in property_stock_fields: + if stock_property in vals: + vals.pop(stock_property) + else: + for stock_property in property_stock_fields: + if stock_property in vals and vals[stock_property] is False: + vals.pop(stock_property) valuation_impacted = False if new_cost_method and new_cost_method != product_category.property_cost_method: valuation_impacted = True @@ -846,6 +861,22 @@ class ProductCategory(models.Model): account_moves._post() return res + + @api.model_create_multi + def create(self, vals_list): + for vals in vals_list: + if 'property_valuation' not in vals or vals['property_valuation'] == 'manual_periodic': + vals['property_stock_account_input_categ_id'] = False + vals['property_stock_account_output_categ_id'] = False + vals['property_stock_valuation_account_id'] = False + if 'property_valuation' in vals and vals['property_valuation'] == 'real_time': + company_id = self.env.company + vals['property_stock_account_input_categ_id'] = vals.get('property_stock_account_input_categ_id', False) or company_id.property_stock_account_input_categ_id + vals['property_stock_account_output_categ_id'] = vals.get('property_stock_account_output_categ_id', False) or company_id.property_stock_account_output_categ_id + vals['property_stock_valuation_account_id'] = vals.get('property_stock_valuation_account_id', False) or company_id.property_stock_valuation_account_id + + return super().create(vals_list) + @api.onchange('property_valuation') def onchange_property_valuation(self): # Remove or set the account stock properties if necessary diff --git a/addons/stock_account/tests/test_stock_valuation_layer_revaluation.py b/addons/stock_account/tests/test_stock_valuation_layer_revaluation.py index 58c6d7fab04..035661b6cfd 100644 --- a/addons/stock_account/tests/test_stock_valuation_layer_revaluation.py +++ b/addons/stock_account/tests/test_stock_valuation_layer_revaluation.py @@ -16,6 +16,7 @@ class TestStockValuationLayerRevaluation(TestStockValuationCommon): 'property_account_expense_id': cls.expense_account.id, }) cls.product1.categ_id.write({ + 'property_valuation': 'real_time', 'property_stock_account_input_categ_id': cls.stock_input_account.id, 'property_stock_account_output_categ_id': cls.stock_output_account.id, 'property_stock_valuation_account_id': cls.stock_valuation_account.id, diff --git a/addons/stock_account/tests/test_stockvaluationlayer.py b/addons/stock_account/tests/test_stockvaluationlayer.py index 653e314ccaf..ebeaea088a4 100644 --- a/addons/stock_account/tests/test_stockvaluationlayer.py +++ b/addons/stock_account/tests/test_stockvaluationlayer.py @@ -895,6 +895,11 @@ class TestStockValuationChangeValuation(TestStockValuationCommon): 'property_stock_valuation_account_id': cls.stock_valuation_account.id, 'property_stock_journal': cls.stock_journal.id, }) + cls.env.company.write({ + 'property_stock_account_input_categ_id': cls.stock_input_account.id, + 'property_stock_account_output_categ_id': cls.stock_output_account.id, + 'property_stock_valuation_account_id': cls.stock_valuation_account.id, + }) def test_standard_manual_to_auto_1(self): self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'