[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#71064

X-original-commit: 60e83f03b871605b7aa281503269f66ac3ea940b
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Signed-off-by: Yuchen Huang <yhu-odoo@users.noreply.github.com>
This commit is contained in:
yhu-odoo
2021-05-19 17:01:08 +00:00
committed by Arnold Moyaux
parent 3556615c3f
commit 2915ac1226
3 changed files with 157 additions and 11 deletions
+13 -1
View File
@@ -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
+136 -1
View File
@@ -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):
@@ -185,3 +186,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)
+8 -9
View File
@@ -333,15 +333,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:
@@ -357,6 +350,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