diff --git a/addons/account/data/data_account_type.xml b/addons/account/data/data_account_type.xml
index ca4676f05f0..54ab23e605f 100644
--- a/addons/account/data/data_account_type.xml
+++ b/addons/account/data/data_account_type.xml
@@ -69,6 +69,7 @@
Current Year Earnings
+ equity
diff --git a/addons/account/models/account.py b/addons/account/models/account.py
index 143ca388763..2d6ef5f10f5 100644
--- a/addons/account/models/account.py
+++ b/addons/account/models/account.py
@@ -41,7 +41,8 @@ class AccountAccountType(models.Model):
('expense', 'Expense'),
('off_balance', 'Off Balance'),
], string="Internal Group",
- help="The 'Internal Group' is used to filter accounts based on the internal group set on the account type.")
+ required=True,
+ help="The 'Internal Group' is used to filter accounts based on the internal group set on the account type.")
note = fields.Text(string='Description')
diff --git a/addons/account/static/src/js/account_selection.js b/addons/account/static/src/js/account_selection.js
new file mode 100644
index 00000000000..c000d5b6fd1
--- /dev/null
+++ b/addons/account/static/src/js/account_selection.js
@@ -0,0 +1,72 @@
+odoo.define('account.hierarchy.selection', function (require) {
+"use strict";
+
+ var core = require('web.core');
+ var relational_fields = require('web.relational_fields');
+ var _t = core._t;
+ var registry = require('web.field_registry');
+
+
+ var FieldSelection = relational_fields.FieldSelection;
+
+ var qweb = core.qweb;
+
+ var HierarchySelection = FieldSelection.extend({
+ _renderEdit: function () {
+ var self = this;
+ var prom = Promise.resolve()
+ if (!self.hierarchy_groups) {
+ prom = this._rpc({
+ model: 'account.account.type',
+ method: 'read',
+ args: [
+ _.filter(_.map(this.values, v => v[0]), v => typeof v == 'number'),
+ ['internal_group'],
+ ],
+ }).then(function(arg) {
+ self.hierarchy_groups = [
+ {
+ 'name': _('Balance Sheet'),
+ 'children': [
+ {'name': _t('Assets'), 'ids': _.map(_.filter(arg, v => v['internal_group'] == 'asset'), v => v['id'])},
+ {'name': _t('Liabilities'), 'ids': _.map(_.filter(arg, v => v['internal_group'] == 'liability' || v['internal_group'] == 'equity'), v => v['id'])},
+ ]
+ },
+ {'name': _t('Profit & Loss'), 'ids': _.map(_.filter(arg, v => v['internal_group'] == 'income' || v['internal_group'] == 'expense'), v => v['id'])},
+ {'name': _t('Other'), 'ids': _.map(_.filter(arg, v => !['asset', 'liability', 'equity', 'income', 'expense'].includes(v['internal_group'])), v => v['id'])},
+ ]
+ });
+ }
+
+ Promise.resolve(prom).then(function() {
+ self.$el.empty();
+ self._addHierarchy(self.$el, self.hierarchy_groups, 0);
+ var value = self.value;
+ if (self.field.type === 'many2one' && value) {
+ value = value.data.id;
+ }
+ self.$el.val(JSON.stringify(value));
+ });
+ },
+ _addHierarchy: function(el, group, level) {
+ var self = this;
+ _.each(group, function(item) {
+ var optgroup = $('').attr(({
+ 'label': $('').html(' '.repeat(3 * level) + item['name']).text(),
+ }))
+ _.each(item['ids'], function(id) {
+ var value = _.find(self.values, v => v[0] == id)
+ optgroup.append($('', {
+ value: JSON.stringify(value[0]),
+ text: value[1],
+ }));
+ })
+ el.append(optgroup)
+ if (item['children']) {
+ self._addHierarchy(el, item['children'], level + 1);
+ }
+ })
+ }
+ });
+ registry.add("account_hierarchy_selection", HierarchySelection);
+});
diff --git a/addons/account/views/account.xml b/addons/account/views/account.xml
index 2e02a3f5753..4bfc5afe7cc 100644
--- a/addons/account/views/account.xml
+++ b/addons/account/views/account.xml
@@ -30,6 +30,7 @@
+
diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml
index 9c72ff247b4..bf519c193c1 100644
--- a/addons/account/views/account_view.xml
+++ b/addons/account/views/account_view.xml
@@ -15,7 +15,7 @@
-
+
@@ -1397,7 +1397,7 @@ action = model.setting_init_bank_account_action()
-
+
diff --git a/addons/point_of_sale/tests/common.py b/addons/point_of_sale/tests/common.py
index dd2a2666fcd..98e5eda1125 100644
--- a/addons/point_of_sale/tests/common.py
+++ b/addons/point_of_sale/tests/common.py
@@ -132,7 +132,8 @@ class TestPoSCommon(TransactionCase):
self.other_receivable_account = self.env['account.account'].create({
'name': 'Other Receivable',
'code': 'RCV00' ,
- 'user_type_id': self.env['account.account.type'].create({'name': 'RCV type', 'type': 'receivable'}).id,
+ 'user_type_id': self.env['account.account.type'].create({'name': 'RCV type', 'type': 'receivable', 'internal_group': 'asset'}).id,
+ 'internal_group': 'asset',
'reconcile': True,
})
diff --git a/addons/sale_mrp/tests/test_sale_mrp_flow.py b/addons/sale_mrp/tests/test_sale_mrp_flow.py
index ecd7f4c4380..07e5f596146 100644
--- a/addons/sale_mrp/tests/test_sale_mrp_flow.py
+++ b/addons/sale_mrp/tests/test_sale_mrp_flow.py
@@ -572,7 +572,7 @@ class TestSaleMrpFlow(common.SavepointCase):
self.company.anglo_saxon_accounting = True
self.partner = self.env.ref('base.res_partner_1')
self.category = self.env.ref('product.product_category_1').copy({'name': 'Test category','property_valuation': 'real_time', 'property_cost_method': 'fifo'})
- account_type = self.env['account.account.type'].create({'name': 'RCV type', 'type': 'other'})
+ account_type = self.env['account.account.type'].create({'name': 'RCV type', 'type': 'other', 'internal_group': 'asset'})
self.account_receiv = self.env['account.account'].create({'name': 'Receivable', 'code': 'RCV00' , 'user_type_id': account_type.id, 'reconcile': True})
account_expense = self.env['account.account'].create({'name': 'Expense', 'code': 'EXP00' , 'user_type_id': account_type.id, 'reconcile': True})
account_output = self.env['account.account'].create({'name': 'Output', 'code': 'OUT00' , 'user_type_id': account_type.id, 'reconcile': True})
diff --git a/addons/stock_landed_costs/tests/common.py b/addons/stock_landed_costs/tests/common.py
index 5c9fb50676e..ac14bb6745e 100644
--- a/addons/stock_landed_costs/tests/common.py
+++ b/addons/stock_landed_costs/tests/common.py
@@ -35,7 +35,8 @@ class TestStockLandedCostsCommon(AccountingTestCase):
'code': "X1101",
'user_type_id': self.env['account.account.type'].create({
'name': 'Expenses',
- 'type': 'other'}).id,
+ 'type': 'other',
+ 'internal_group': 'liability'}).id,
'reconcile': True})
self.expenses_journal = self.env['account.journal'].create({
'name': 'Expenses - Test',