Skip to content

Commit

Permalink
[IMP] account: refactor account types
Browse files Browse the repository at this point in the history
Task: 2856281

- Remove user_type_id, account.account.type model, internal_type
- Add account_type that is a simple selection field
- Move internal_group and include_initial_balance to account.account
- Because of these changes, type_control_ids on account.journal is also removed

closes #93212

Related: odoo/documentation#2223
Related: odoo/upgrade#3595
Related: odoo/enterprise#28205
Signed-off-by: Cedric Snauwaert <csn@odoo.com>
  • Loading branch information
aliyatastemirova committed Jul 8, 2022
1 parent cb68632 commit 26b2472
Show file tree
Hide file tree
Showing 171 changed files with 25,224 additions and 25,458 deletions.
2 changes: 0 additions & 2 deletions addons/account/__manifest__.py
Expand Up @@ -19,7 +19,6 @@
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
'data/data_account_type.xml',
'data/account_data.xml',
'data/digest_data.xml',
'views/account_report.xml',
Expand All @@ -33,7 +32,6 @@
'views/account_move_views.xml',
'wizard/setup_wizards_view.xml',
'wizard/pos_box.xml',
'views/account_account_type_views.xml',
'views/account_account_views.xml',
'views/account_group_views.xml',
'views/account_journal_views.xml',
Expand Down
106 changes: 0 additions & 106 deletions addons/account/data/data_account_type.xml

This file was deleted.

10 changes: 5 additions & 5 deletions addons/account/demo/account_demo.py
Expand Up @@ -173,7 +173,7 @@ def _get_demo_data_reconcile_model(self):
'label': 'Due amount',
'account_id': self._get_demo_account(
'income',
'account.data_account_type_revenue',
'income',
self.env.company,
).id,
'amount_type': 'regex',
Expand All @@ -183,7 +183,7 @@ def _get_demo_data_reconcile_model(self):
'label': 'Bank Fees',
'account_id': self._get_demo_account(
'cost_of_goods_sold',
'account.data_account_type_direct_costs',
'expense_direct_cost',
self.env.company,
).id,
'amount_type': 'percentage',
Expand Down Expand Up @@ -336,11 +336,11 @@ def _post_create_demo_data(self, created):
created.button_post()

@api.model
def _get_demo_account(self, xml_id, user_type_id, company):
def _get_demo_account(self, xml_id, account_type, company):
"""Find the most appropriate account possible for demo data creation.
:param xml_id (str): the xml_id of the account template in the generic coa
:param user_type_id (str): the full xml_id of the account type wanted
:param account_type (str): the full xml_id of the account type wanted
:param company (Model<res.company>): the company for which we search the account
:return (Model<account.account>): the most appropriate record found
"""
Expand All @@ -351,7 +351,7 @@ def _get_demo_account(self, xml_id, user_type_id, company):
('module', '=like', 'l10n%')
], limit=1).res_id)
or self.env['account.account'].search([
('user_type_id', '=', self.env.ref(user_type_id).id),
('account_type', '=', account_type),
('company_id', '=', company.id)
], limit=1)
or self.env['account.account'].search([('company_id', '=', company.id)], limit=1)
Expand Down
112 changes: 64 additions & 48 deletions addons/account/models/account_account.py
Expand Up @@ -4,52 +4,23 @@
from odoo.exceptions import UserError, ValidationError


class AccountAccountType(models.Model):
_name = "account.account.type"
_description = "Account Type"

name = fields.Char(string='Account Type', required=True, translate=True)
include_initial_balance = fields.Boolean(string="Bring Accounts Balance Forward", help="Used in reports to know if we should consider journal items from the beginning of time instead of from the fiscal year only. Account types that should be reset to zero at each new fiscal year (like expenses, revenue..) should not have this option set.")
type = fields.Selection([
('other', 'Regular'),
('receivable', 'Receivable'),
('payable', 'Payable'),
('liquidity', 'Liquidity'),
], required=True, default='other',
help="The 'Internal Type' is used for features available on "\
"different types of accounts: liquidity type is for cash or bank accounts"\
", payable/receivable is for vendor/customer accounts.")
internal_group = fields.Selection([
('equity', 'Equity'),
('asset', 'Asset'),
('liability', 'Liability'),
('income', 'Income'),
('expense', 'Expense'),
('off_balance', 'Off Balance'),
], string="Internal Group",
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')


class AccountAccount(models.Model):
_name = "account.account"
_inherit = ['mail.thread']
_description = "Account"
_order = "is_off_balance, code, company_id"
_check_company_auto = True

@api.constrains('internal_type', 'reconcile')
@api.constrains('account_type', 'reconcile')
def _check_reconcile(self):
for account in self:
if account.internal_type in ('receivable', 'payable') and account.reconcile == False:
if account.account_type in ('asset_receivable', 'liability_payable') and not account.reconcile:
raise ValidationError(_('You cannot have a receivable/payable account that is not reconcilable. (account code: %s)', account.code))

@api.constrains('user_type_id')
def _check_user_type_id_unique_current_year_earning(self):
data_unaffected_earnings = self.env.ref('account.data_unaffected_earnings')
@api.constrains('account_type')
def _check_account_type_unique_current_year_earning(self):
result = self._read_group(
domain=[('user_type_id', '=', data_unaffected_earnings.id)],
domain=[('account_type', '=', 'equity_unaffected')],
fields=['company_id', 'ids:array_agg(id)'],
groupby=['company_id'],
)
Expand All @@ -64,10 +35,46 @@ def _check_user_type_id_unique_current_year_earning(self):
code = fields.Char(size=64, required=True, tracking=True)
deprecated = fields.Boolean(default=False, tracking=True)
used = fields.Boolean(compute='_compute_used', search='_search_used')
user_type_id = fields.Many2one('account.account.type', string='Type', required=True, tracking=True,
help="Account Type is used for information purpose, to generate country-specific legal reports, and set the rules to close a fiscal year and generate opening entries.")
internal_type = fields.Selection(related='user_type_id.type', string="Internal Type", store=True, readonly=True)
internal_group = fields.Selection(related='user_type_id.internal_group', string="Internal Group", store=True, readonly=True)
account_type = fields.Selection(
selection=[
("asset_receivable", "Receivable"),
("asset_cash", "Bank and Cash"),
("asset_current", "Current Assets"),
("asset_non_current", "Non-current Assets"),
("asset_prepayments", "Prepayments"),
("asset_fixed", "Fixed Assets"),
("liability_payable", "Payable"),
("liability_credit_card", "Credit Card"),
("liability_current", "Current Liabilities"),
("liability_non_current", "Non-current Liabilities"),
("equity", "Equity"),
("equity_unaffected", "Current Year Earnings"),
("income", "Income"),
("income_other", "Other Income"),
("expense", "Expenses"),
("expense_depreciation", "Depreciation"),
("expense_direct_cost", "Cost of Revenue"),
("off_balance", "Off-Balance Sheet"),
],
string="Type", tracking=True,
required=True,
help="Account Type is used for information purpose, to generate country-specific legal reports, and set the rules to close a fiscal year and generate opening entries."
)
include_initial_balance = fields.Boolean(string="Bring Accounts Balance Forward",
help="Used in reports to know if we should consider journal items from the beginning of time instead of from the fiscal year only. Account types that should be reset to zero at each new fiscal year (like expenses, revenue..) should not have this option set.",
compute="_compute_include_initial_balance",
store=True)
internal_group = fields.Selection(
selection=[
('equity', 'Equity'),
('asset', 'Asset'),
('liability', 'Liability'),
('income', 'Income'),
('expense', 'Expense'),
('off_balance', 'Off Balance'),
],
string="Internal Group", readonly=True, compute="_compute_internal_group", store=True
)
#has_unreconciled_entries = fields.Boolean(compute='_compute_has_unreconciled_entries',
# help="The account has at least one unreconciled debit and credit since last time the invoices & payments matching was performed.")
reconcile = fields.Boolean(string='Allow Reconciliation', default=False, tracking=True,
Expand Down Expand Up @@ -216,21 +223,19 @@ def _check_company_consistency(self):
if self._cr.fetchone():
raise UserError(_("You can't change the company of your account since there are some journal items linked to it."))

@api.constrains('user_type_id')
def _check_user_type_id_sales_purchase_journal(self):
@api.constrains('account_type')
def _check_account_type_sales_purchase_journal(self):
if not self:
return

self.flush_recordset(['user_type_id'])
self.env['account.account.type'].flush_model(['type'])
self.env['account.account'].flush_model(['account_type'])
self.env['account.journal'].flush_model(['type', 'default_account_id'])
self._cr.execute('''
SELECT account.id
FROM account_account account
JOIN account_account_type acc_type ON account.user_type_id = acc_type.id
JOIN account_journal journal ON journal.default_account_id = account.id
WHERE account.id IN %s
AND acc_type.type IN ('receivable', 'payable')
AND account.account_type IN ('asset_receivable', 'liability_payable')
AND journal.type IN ('sale', 'purchase')
LIMIT 1;
''', [tuple(self.ids)])
Expand Down Expand Up @@ -366,6 +371,17 @@ def _compute_is_off_balance(self):
for account in self:
account.is_off_balance = account.internal_group == "off_balance"

@api.depends('account_type')
def _compute_include_initial_balance(self):
for account in self:
account.include_initial_balance = account.account_type not in ('income', 'income_other', 'expense', 'expense_depreciation', 'expense_direct_cost', 'off_balance')

@api.depends('account_type')
def _compute_internal_group(self):
for account in self:
if account.account_type:
account.internal_group = 'off_balance' if account.account_type == 'off_balance' else account.account_type.split('_')[0]

def _set_opening_debit(self):
for record in self:
record._set_opening_debit_credit(record.opening_debit, 'debit')
Expand Down Expand Up @@ -484,10 +500,10 @@ def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_ui
domain = ['&', '!'] + domain[1:]
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)

@api.onchange('user_type_id')
def _onchange_user_type_id(self):
self.reconcile = self.internal_type in ('receivable', 'payable')
if self.internal_type == 'liquidity':
@api.onchange('account_type')
def _onchange_account_type(self):
self.reconcile = self.account_type in ('asset_receivable', 'liability_payable')
if self.account_type in ('asset_cash', 'liability_credit_card'):
self.reconcile = False
elif self.internal_group == 'off_balance':
self.reconcile = False
Expand Down
2 changes: 1 addition & 1 deletion addons/account/models/account_bank_statement.py
Expand Up @@ -980,7 +980,7 @@ def _get_default_amls_matching_domain(self):
('account_id.reconcile', '=', True),
# Special domain for payments.
'|',
('account_id.internal_type', 'not in', ('receivable', 'payable')),
('account_id.account_type', 'not in', ('asset_receivable', 'liability_payable')),
('payment_id', '=', False),
# Special domain for statement lines.
('statement_line_id', '!=', self.id),
Expand Down

0 comments on commit 26b2472

Please sign in to comment.