[FIX] account: analytic_distribution on counterpart of transfer

To reproduce:
- Create 2 lines with the same balance but only one has an analytic_distribution (of 100% on an analytic account).
- Create a transfer of accounts for these
=> The counterpart has a distribution of 100% or no distribution.
Indeed, we simply put the distribution of the last line.

It makes no sense: analytic "balance" is generated and does not reflect the transfer move.
We should make a prorata of the distributions of the lines to transfer.

closes odoo/odoo#161982

X-original-commit: dcfe607d48021902c88b79a571a15559434d1592
Signed-off-by: Laurent Smet (las) <las@odoo.com>
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
This commit is contained in:
Gauthier Wala (gawa)
2024-04-16 10:32:31 +00:00
parent b4a798d843
commit 994aef18c5
2 changed files with 90 additions and 4 deletions
@@ -192,6 +192,23 @@ class TestTransferWizard(AccountTestInvoicingCommon):
})
cls.move_2.action_post()
analytic_plan_1, analytic_plan_2 = cls.env['account.analytic.plan'].create([
{'name': 'Plan Test 1'},
{'name': 'Plan Test 2'},
])
cls.analytic_account_1, cls.analytic_account_2 = cls.env['account.analytic.account'].create([
{
'name': 'test_analytic_account_1',
'plan_id': analytic_plan_1.id,
'code': 'TESTEUH1'
},
{
'name': 'test_analytic_account_2',
'plan_id': analytic_plan_2.id,
'code': 'TESTEUH2'
},
])
@freeze_time('2024-03-13')
def test_transfer_default_tax(self):
""" Make sure default taxes on accounts are not computed on transfer moves
@@ -438,3 +455,53 @@ class TestTransferWizard(AccountTestInvoicingCommon):
self.assertRecordValues(destination_line, [
{'account_id': self.accounts[0].id, 'amount_currency': 0.0, 'currency_id': self.test_currency_1.id, 'balance': -1000}
])
def test_transfer_wizard_analytic(self):
""" Tests that the analytic distribution is transmitted when doing a transfer with the wizard """
invoice = self.env['account.move'].create([
{
'move_type': 'out_invoice',
'partner_id': self.partner_a.id,
'invoice_date': '2017-01-01',
'journal_id': self.company_data['default_journal_sale'].id,
'invoice_line_ids': [
Command.create({
'quantity': 1,
'price_unit': 1000.0,
'account_id': self.company_data['default_account_revenue'].id,
'analytic_distribution': {self.analytic_account_1.id: 100},
}),
Command.create({
'quantity': 1,
'price_unit': 2000.0,
'account_id': self.company_data['default_account_revenue'].id,
'analytic_distribution': {self.analytic_account_1.id: 50, self.analytic_account_2.id: 50},
}),
Command.create({
'quantity': 1,
'price_unit': 1000.0,
'account_id': self.company_data['default_account_revenue'].id,
'analytic_distribution': False,
}),
],
}
])
invoice.action_post()
wizard = self.env['account.automatic.entry.wizard'].with_context(
active_model='account.move.line',
active_ids=invoice.invoice_line_ids.ids
).create({
'action': 'change_account',
'date': '2018-01-01',
'journal_id': self.journal.id,
'destination_account_id': self.receivable_account.id,
})
transfer_move = self.env['account.move'].browse(wizard.do_action()['res_id'])
self.assertRecordValues(transfer_move.line_ids, [
{'balance': -4000, 'analytic_distribution': {str(self.analytic_account_1.id): 50, str(self.analytic_account_2.id): 25}},
{'balance': 1000, 'analytic_distribution': {str(self.analytic_account_1.id): 100}},
{'balance': 2000, 'analytic_distribution': {str(self.analytic_account_1.id): 50, str(self.analytic_account_2.id): 50}},
{'balance': 1000, 'analytic_distribution': False},
])
@@ -161,6 +161,7 @@ class AutomaticEntryWizard(models.TransientModel):
# Group data from selected move lines
counterpart_balances = defaultdict(lambda: defaultdict(lambda: 0))
counterpart_distribution_amount = defaultdict(lambda: defaultdict(lambda: {}))
grouped_source_lines = defaultdict(lambda: self.env['account.move.line'])
for line in self.move_line_ids.filtered(lambda x: x.account_id != self.destination_account_id):
@@ -171,9 +172,17 @@ class AutomaticEntryWizard(models.TransientModel):
counterpart_currency = self.destination_account_id.currency_id
counterpart_amount_currency = self.company_id.currency_id._convert(line.balance, self.destination_account_id.currency_id, self.company_id, line.date)
counterpart_balances[(line.partner_id, counterpart_currency)]['amount_currency'] += counterpart_amount_currency
counterpart_balances[(line.partner_id, counterpart_currency)]['balance'] += line.balance
counterpart_balances[(line.partner_id, counterpart_currency)]['analytic_distribution'] = line.analytic_distribution
grouping_key = (line.partner_id, counterpart_currency)
counterpart_balances[grouping_key]['amount_currency'] += counterpart_amount_currency
counterpart_balances[grouping_key]['balance'] += line.balance
if line.analytic_distribution:
for account_id, distribution in line.analytic_distribution.items():
# For the counterpart, we will need to make a prorata of the different distribution of the lines
# This computes the total balance for each analytic account, for each counterpart line to generate
distribution_values = counterpart_distribution_amount[grouping_key]
distribution_values[account_id] = (line.balance * distribution + distribution_values.get(account_id, 0) * 100) / 100
counterpart_balances[grouping_key]['analytic_distribution'] = counterpart_distribution_amount[grouping_key] or {}
grouped_source_lines[(
line.partner_id,
line.currency_id,
@@ -186,6 +195,16 @@ class AutomaticEntryWizard(models.TransientModel):
source_accounts = self.move_line_ids.mapped('account_id')
counterpart_label = len(source_accounts) == 1 and _("Transfer from %s", source_accounts.display_name) or _("Transfer counterpart")
# We divide the amount for each account by the total balance to reflect the lines counter-parted
analytic_distribution = {
account_id: (
100
if counterpart_currency.is_zero(counterpart_vals['balance'])
else 100 * distribution_amount / counterpart_vals['balance']
)
for account_id, distribution_amount in counterpart_vals['analytic_distribution'].items()
}
if not counterpart_currency.is_zero(counterpart_vals['amount_currency']) or not self.company_id.currency_id.is_zero(counterpart_vals['balance']):
line_vals.append({
'name': counterpart_label,
@@ -195,7 +214,7 @@ class AutomaticEntryWizard(models.TransientModel):
'partner_id': counterpart_partner.id or None,
'amount_currency': counterpart_currency.round((counterpart_vals['balance'] < 0 and -1 or 1) * abs(counterpart_vals['amount_currency'])) or 0,
'currency_id': counterpart_currency.id,
'analytic_distribution': counterpart_vals['analytic_distribution'],
'analytic_distribution': analytic_distribution,
})
# Generate change_account lines' vals