[FIX] account, hr_expense: fix reconciliation function
Steps to reproduce the bug: - Install Accounting and Expense app - Go to accounting settings > enable cash basis option - Go to accounting > configuration > accounting > taxes - Create a new tax or choose an existing one e.g “Tax abc”: Tax Computation = `”Percentage of Price”` Tax Type = `”Purchases”` Choose any value for amount Select "Based on Payment" in tax due choose an account with the "Allow Reconciliation" option activated in the Cash Basis Transition Account field Save - Go to expenses > Expense Reports > All reports > Create a new one : - Add 2 expense and for both set up the taxes to "Tax abc" and unit price > 0 - Submit to manager - Approve - Post journal entries - Register a payment Problem: A user error with the following message is triggered: “You are trying to reconcile some entries that are already reconciled” In the use case we have two expenses and for each, an `" account.partial.reconcile "` will be created, so we will loop twice and therefore add twice all the `”account.move.line”` linked to the taxes in the dict `" to_reconcile_after "`: https://github.com/odoo/odoo/blob/beccf82e09d536255d9d9cb9bfe58ebae2559843/addons/account/models/account_partial_reconcile.py#L585 Then we loop to reconcile all the `" account.move.line "` which are in the dict `" to_reconcile_after "`, but since we added them all twice, at each turn of the loop we give them all as a parameter of the “reconcile” function without checking whether they are already reconciled or not. opw-2565934 closes odoo/odoo#74432 X-original-commit: fb2b1482f5d3dec924b08e08dc915d6608c7d6b3 Signed-off-by: Laurent Smet <smetl@users.noreply.github.com> Signed-off-by: Djamel Touati <DjamelTouati@users.noreply.github.com>
This commit is contained in:
@@ -503,13 +503,20 @@ class AccountPartialReconcile(models.Model):
|
||||
moves._post(soft=False)
|
||||
|
||||
# Reconcile the tax lines being on a reconcile tax basis transfer account.
|
||||
for line, move_index, sequence in to_reconcile_after:
|
||||
for lines, move_index, sequence in to_reconcile_after:
|
||||
|
||||
# In expenses, all move lines are created manually without any grouping on tax lines.
|
||||
# In that case, 'lines' could be already reconciled.
|
||||
lines = lines.filtered(lambda x: not x.reconciled)
|
||||
if not lines:
|
||||
continue
|
||||
|
||||
counterpart_line = moves[move_index].line_ids.filtered(lambda line: line.sequence == sequence)
|
||||
|
||||
# When dealing with tiny amounts, the line could have a zero amount and then, be already reconciled.
|
||||
if counterpart_line.reconciled:
|
||||
continue
|
||||
|
||||
(line + counterpart_line).reconcile()
|
||||
(lines + counterpart_line).reconcile()
|
||||
|
||||
return moves
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.addons.hr_expense.tests.common import TestExpenseCommon
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests import tagged, Form
|
||||
from odoo import fields
|
||||
|
||||
|
||||
@@ -223,3 +223,57 @@ class TestExpenses(TestExpenseCommon):
|
||||
|
||||
# Assert not "Cannot create unbalanced journal entry" error.
|
||||
expense.action_sheet_move_create()
|
||||
|
||||
def test_reconcile_payment(self):
|
||||
tax = self.env['account.tax'].create({
|
||||
'name': 'tax abc',
|
||||
'type_tax_use': 'purchase',
|
||||
'amount_type': 'percent',
|
||||
'amount': 15,
|
||||
'price_include': False,
|
||||
'include_base_amount': False,
|
||||
'tax_exigibility': 'on_payment'
|
||||
})
|
||||
current_assets_type = self.env.ref('account.data_account_type_current_assets')
|
||||
company = self.env.company.id
|
||||
tax.cash_basis_transition_account_id = self.env['account.account'].create({
|
||||
'name': "test",
|
||||
'code': 999991,
|
||||
'reconcile': True,
|
||||
'user_type_id': current_assets_type.id,
|
||||
'company_id': company,
|
||||
}).id
|
||||
|
||||
sheet = self.env['hr.expense.sheet'].create({
|
||||
'company_id': company,
|
||||
'employee_id': self.expense_employee.id,
|
||||
'name': 'test sheet',
|
||||
'expense_line_ids': [
|
||||
(0, 0, {
|
||||
'name': 'expense_1',
|
||||
'date': '2016-01-01',
|
||||
'product_id': self.product_a.id,
|
||||
'unit_amount': 10.0,
|
||||
'employee_id': self.expense_employee.id,
|
||||
'tax_ids': tax
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': 'expense_2',
|
||||
'date': '2016-01-01',
|
||||
'product_id': self.product_a.id,
|
||||
'unit_amount': 1.0,
|
||||
'employee_id': self.expense_employee.id,
|
||||
'tax_ids': tax
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
#actions
|
||||
sheet.action_submit_sheet()
|
||||
sheet.approve_expense_sheets()
|
||||
sheet.action_sheet_move_create()
|
||||
action_data = sheet.action_register_payment()
|
||||
wizard = Form(self.env['account.payment.register'].with_context(action_data['context'])).save()
|
||||
wizard.action_create_payments()
|
||||
self.assertEqual(sheet.state, 'done', 'all account.move.line linked to expenses must be reconciled after payment')
|
||||
|
||||
Reference in New Issue
Block a user