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