From cc895ce3eac1f2e74d593e5fdcafb798648b6ff3 Mon Sep 17 00:00:00 2001 From: "Ricardo Gomes Rodrigues (rigr)" Date: Mon, 5 Sep 2022 11:50:44 +0000 Subject: [PATCH] [FIX] account: wrong account suggestion if no invoice exists for set partner Steps: - New invoice - Select a partner that has no invoices yet - Create a new line - The default account is quite random Fix: Only use the most frequent account for the set partner if there are existing invoices for that partner. Otherwise we fallback on the default account of the invoice's journal (instead of the suspense account). closes odoo/odoo#102350 Task-id: 2972993 X-original-commit: 471924c0d0e2647a25aa38507224f8321b598211 Signed-off-by: Florian Gilbert (flg) Signed-off-by: Ricardo Gomes Rodrigues (rigr) --- addons/account/models/account_account.py | 28 +++++++++++++++++----- addons/account/models/account_move_line.py | 7 +++--- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/addons/account/models/account_account.py b/addons/account/models/account_account.py index ace958756b4..b88135072c8 100644 --- a/addons/account/models/account_account.py +++ b/addons/account/models/account_account.py @@ -506,12 +506,19 @@ class AccountAccount(models.Model): return super(AccountAccount, contextual_self).default_get(default_fields) @api.model - def _order_by_frequency_per_partner(self, company_id, partner_id, move_type=None, limit=None): + def _get_most_frequent_accounts_for_partner(self, company_id, partner_id, move_type, filter_never_user_accounts=False, limit=None): """ - Returns the accounts ordered from most used to least used for a given partner - and filtered according to the move type. + Returns the accounts ordered from most frequent to least frequent for a given partner + and filtered according to the move type + :param company_id: the company id + :param partner_id: the partner id for which we want to retrieve the most frequent accounts + :param move_type: the type of the move to know which type of accounts to retrieve + :param filter_never_user_accounts: True if we should filter out accounts never used for the partner + :param limit: the maximum number of accounts to retrieve + :returns: List of account ids, ordered by frequency (from most to least frequent) """ - limit = "LIMIT 1" if limit is not None else "" + join = "INNER JOIN" if filter_never_user_accounts else "LEFT JOIN" + limit = f"LIMIT {limit:d}" if limit else "" where_internal_group = "" if move_type in self.env['account.move'].get_inbound_types(include_receipts=True): where_internal_group = "AND account.internal_group = 'income'" @@ -520,7 +527,7 @@ class AccountAccount(models.Model): self._cr.execute(f""" SELECT account.id FROM account_account account - LEFT JOIN account_move_line aml + {join} account_move_line aml ON aml.account_id = account.id AND aml.partner_id = %s AND account.deprecated = FALSE @@ -534,10 +541,19 @@ class AccountAccount(models.Model): """, [partner_id, company_id]) return [r[0] for r in self._cr.fetchall()] + @api.model + def _get_most_frequent_account_for_partner(self, company_id, partner_id, move_type=None): + most_frequent_account = self._get_most_frequent_accounts_for_partner(company_id, partner_id, move_type, filter_never_user_accounts=True, limit=1) + return most_frequent_account[0] if most_frequent_account else False + + @api.model + def _order_accounts_by_frequency_for_partner(self, company_id, partner_id, move_type=None): + return self._get_most_frequent_accounts_for_partner(company_id, partner_id, move_type) + @api.model def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None): if not name and self._context.get('partner_id') and self._context.get('move_type'): - return self._order_by_frequency_per_partner( + return self._order_accounts_by_frequency_for_partner( self.env.company.id, self._context.get('partner_id'), self._context.get('move_type')) args = args or [] domain = [] diff --git a/addons/account/models/account_move_line.py b/addons/account/models/account_move_line.py index 246b3e15c87..e25088a0b14 100644 --- a/addons/account/models/account_move_line.py +++ b/addons/account/models/account_move_line.py @@ -569,12 +569,11 @@ class AccountMoveLine(models.Model): elif line.move_id.is_purchase_document(include_receipts=True): line.account_id = accounts['expense'] or line.account_id elif line.partner_id: - line.account_id = self.env['account.account']._order_by_frequency_per_partner( + line.account_id = self.env['account.account']._get_most_frequent_account_for_partner( company_id=line.company_id.id, partner_id=line.partner_id.id, move_type=line.move_id.move_type, - limit=1, - )[0] + ) for line in self: if not line.account_id and line.display_type not in ('line_section', 'line_note'): previous_two_accounts = line.move_id.line_ids.filtered( @@ -583,7 +582,7 @@ class AccountMoveLine(models.Model): if len(previous_two_accounts) == 1: line.account_id = previous_two_accounts else: - line.account_id = line.company_id.account_journal_suspense_account_id + line.account_id = line.move_id.journal_id.default_account_id @api.depends('move_id') def _compute_balance(self):