[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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user