summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryhu-odoo <yhu@odoo.com>2021-03-05 10:56:16 +0000
committerArnold Moyaux <arm@odoo.com>2021-05-19 13:20:35 +0000
commit60e83f03b871605b7aa281503269f66ac3ea940b (patch)
tree3a32ff1c3c8b8eab792fd3e07c1c32c787746b0c
parent91dd6171dac567e5f0185e53982ede3b166cfe7c (diff)
[IMP](stock,mrp)_account: use location valuation account
Previous fix f056254d1c5153467b10d9581214ff6d1348be76 didn't take the situation when production location has its own valuation accounts into consideration. Fix it in this commit. opw-2476417 closes odoo/odoo#67478 Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
-rw-r--r--addons/mrp_account/models/stock_move.py14
-rw-r--r--addons/mrp_account/tests/test_mrp_account.py137
-rw-r--r--addons/stock_account/models/stock_move.py19
3 files changed, 157 insertions, 13 deletions
diff --git a/addons/mrp_account/models/stock_move.py b/addons/mrp_account/models/stock_move.py
index f5c7f9be12b..79af6021c62 100644
--- a/addons/mrp_account/models/stock_move.py
+++ b/addons/mrp_account/models/stock_move.py
@@ -7,6 +7,18 @@ class StockMove(models.Model):
_inherit = "stock.move"
def _is_returned(self, valued_type):
- if self.unbuild_id and self.unbuild_id.mo_id: # unbuilding a MO
+ if self.unbuild_id:
return True
return super()._is_returned(valued_type)
+
+ def _get_src_account(self, accounts_data):
+ if not self.unbuild_id:
+ return super()._get_src_account(accounts_data)
+ else:
+ return self.location_dest_id.valuation_out_account_id.id or accounts_data['stock_input'].id
+
+ def _get_dest_account(self, accounts_data):
+ if not self.unbuild_id:
+ return super()._get_dest_account(accounts_data)
+ else:
+ return self.location_id.valuation_in_account_id.id or accounts_data['stock_output'].id
diff --git a/addons/mrp_account/tests/test_mrp_account.py b/addons/mrp_account/tests/test_mrp_account.py
index f827a0eb023..3464e1474a6 100644
--- a/addons/mrp_account/tests/test_mrp_account.py
+++ b/addons/mrp_account/tests/test_mrp_account.py
@@ -2,7 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.mrp.tests.common import TestMrpCommon
-from odoo.tests import Form
+from odoo.addons.stock_account.tests.test_account_move import TestAccountMove
+from odoo.tests import Form, tagged
class TestMrpAccount(TestMrpCommon):
@@ -188,3 +189,137 @@ class TestMrpAccount(TestMrpCommon):
# 1 table head at 20 + 4 table leg at 15 + 4 bolt at 10 + 10 screw at 10 + 1*20 (extra cost)
self.assertEqual(move_value, 141, 'Thing should have the correct price')
+
+
+@tagged("post_install", "-at_install")
+class TestMrpAccountMove(TestAccountMove):
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.product_B = cls.env["product.product"].create(
+ {
+ "name": "Product B",
+ "type": "product",
+ "default_code": "prda",
+ "categ_id": cls.env.ref("product.product_category_all").id,
+ "taxes_id": [(5, 0, 0)],
+ "supplier_taxes_id": [(5, 0, 0)],
+ "lst_price": 100.0,
+ "standard_price": 10.0,
+ "property_account_income_id": cls.company_data["default_account_revenue"].id,
+ "property_account_expense_id": cls.company_data["default_account_expense"].id,
+ }
+ )
+ cls.bom = cls.env['mrp.bom'].create({
+ 'product_id': cls.product_A.id,
+ 'product_tmpl_id': cls.product_A.product_tmpl_id.id,
+ 'product_qty': 1.0,
+ 'bom_line_ids': [
+ (0, 0, {'product_id': cls.product_B.id, 'product_qty': 1}),
+ ]})
+
+ def test_unbuild_account_00(self):
+ """Test when after unbuild, the journal entries are the reversal of the
+ journal entries created when produce the product.
+ """
+ # build
+ production_form = Form(self.env['mrp.production'])
+ production_form.product_id = self.product_A
+ production_form.bom_id = self.bom
+ production_form.product_qty = 1
+ production = production_form.save()
+ production.action_confirm()
+ mo_form = Form(production)
+ mo_form.qty_producing = 1
+ production = mo_form.save()
+ production._post_inventory()
+ production.button_mark_done()
+
+ # finished product move
+ productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('credit', '=', 0)])
+ productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('debit', '=', 0)])
+ self.assertEqual(productA_debit_line.account_id, self.stock_valuation_account)
+ self.assertEqual(productA_credit_line.account_id, self.stock_input_account)
+ # component move
+ productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('credit', '=', 0)])
+ productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('debit', '=', 0)])
+ self.assertEqual(productB_debit_line.account_id, self.stock_output_account)
+ self.assertEqual(productB_credit_line.account_id, self.stock_valuation_account)
+
+ # unbuild
+ res_dict = production.button_unbuild()
+ wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
+ wizard.action_validate()
+
+ # finished product move
+ productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('credit', '=', 0)])
+ productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('debit', '=', 0)])
+ self.assertEqual(productA_debit_line.account_id, self.stock_input_account)
+ self.assertEqual(productA_credit_line.account_id, self.stock_valuation_account)
+ # component move
+ productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('credit', '=', 0)])
+ productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('debit', '=', 0)])
+ self.assertEqual(productB_debit_line.account_id, self.stock_valuation_account)
+ self.assertEqual(productB_credit_line.account_id, self.stock_output_account)
+
+ def test_unbuild_account_01(self):
+ """Test when production location has its valuation accounts. After unbuild,
+ the journal entries are the reversal of the journal entries created when
+ produce the product.
+ """
+ # set accounts for production location
+ production_location = self.product_A.property_stock_production
+ wip_incoming_account = self.env['account.account'].create({
+ 'name': 'wip incoming',
+ 'code': '000001',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ wip_outgoing_account = self.env['account.account'].create({
+ 'name': 'wip outgoing',
+ 'code': '000002',
+ 'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
+ })
+ production_location.write({
+ 'valuation_in_account_id': wip_incoming_account.id,
+ 'valuation_out_account_id': wip_outgoing_account.id,
+ })
+
+ # build
+ production_form = Form(self.env['mrp.production'])
+ production_form.product_id = self.product_A
+ production_form.bom_id = self.bom
+ production_form.product_qty = 1
+ production = production_form.save()
+ production.action_confirm()
+ mo_form = Form(production)
+ mo_form.qty_producing = 1
+ production = mo_form.save()
+ production._post_inventory()
+ production.button_mark_done()
+
+ # finished product move
+ productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('credit', '=', 0)])
+ productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product A'), ('debit', '=', 0)])
+ self.assertEqual(productA_debit_line.account_id, self.stock_valuation_account)
+ self.assertEqual(productA_credit_line.account_id, wip_outgoing_account)
+ # component move
+ productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('credit', '=', 0)])
+ productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'MO%Product B'), ('debit', '=', 0)])
+ self.assertEqual(productB_debit_line.account_id, wip_incoming_account)
+ self.assertEqual(productB_credit_line.account_id, self.stock_valuation_account)
+
+ # unbuild
+ res_dict = production.button_unbuild()
+ wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save()
+ wizard.action_validate()
+
+ productA_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('credit', '=', 0)])
+ productA_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product A'), ('debit', '=', 0)])
+ self.assertEqual(productA_debit_line.account_id, wip_outgoing_account)
+ self.assertEqual(productA_credit_line.account_id, self.stock_valuation_account)
+ # component move
+ productB_debit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('credit', '=', 0)])
+ productB_credit_line = self.env['account.move.line'].search([('ref', 'ilike', 'UB%Product B'), ('debit', '=', 0)])
+ self.assertEqual(productB_debit_line.account_id, self.stock_valuation_account)
+ self.assertEqual(productB_credit_line.account_id, wip_incoming_account)
diff --git a/addons/stock_account/models/stock_move.py b/addons/stock_account/models/stock_move.py
index 4057e88a1dc..336f9f53a55 100644
--- a/addons/stock_account/models/stock_move.py
+++ b/addons/stock_account/models/stock_move.py
@@ -338,15 +338,8 @@ class StockMove(models.Model):
self = self.with_company(self.company_id)
accounts_data = self.product_id.product_tmpl_id.get_product_accounts()
- if self.location_id.valuation_out_account_id:
- acc_src = self.location_id.valuation_out_account_id.id
- else:
- acc_src = accounts_data['stock_input'].id
-
- if self.location_dest_id.valuation_in_account_id:
- acc_dest = self.location_dest_id.valuation_in_account_id.id
- else:
- acc_dest = accounts_data['stock_output'].id
+ acc_src = self._get_src_account(accounts_data)
+ acc_dest = self._get_dest_account(accounts_data)
acc_valuation = accounts_data.get('stock_valuation', False)
if acc_valuation:
@@ -362,6 +355,12 @@ class StockMove(models.Model):
journal_id = accounts_data['stock_journal'].id
return journal_id, acc_src, acc_dest, acc_valuation
+ def _get_src_account(self, accounts_data):
+ return self.location_id.valuation_out_account_id.id or accounts_data['stock_input'].id
+
+ def _get_dest_account(self, accounts_data):
+ return self.location_dest_id.valuation_in_account_id.id or accounts_data['stock_output'].id
+
def _prepare_account_move_line(self, qty, cost, credit_account_id, debit_account_id, description):
"""
Generate the account.move.line values to post to track the stock valuation difference due to the
@@ -466,8 +465,6 @@ class StockMove(models.Model):
# if the move isn't owned by the company, we don't make any valuation
return False
- location_from = self.location_id
- location_to = self.location_dest_id
company_from = self._is_out() and self.mapped('move_line_ids.location_id.company_id') or False
company_to = self._is_in() and self.mapped('move_line_ids.location_dest_id.company_id') or False