[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:
Touati Djamel (otd)
2021-07-29 16:04:32 +00:00
parent 2c4bcceb22
commit 8f6e85f752
2 changed files with 64 additions and 3 deletions
@@ -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
+55 -1
View File
@@ -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')