[FIX] account: reconciliation widget: make invoice matching reconciliation models work with write-off lines
Use case: 1) Create an invoice matching reconciliation model, matching 90% percent of the amount, with a write-off line applying a 100% write-off of the remaining amount. 2) Create a 100€ invoice 3) Create a bank statement with a 90€ statement line whose payment reference corresponds to the one of the invoice 4) Click 'reconcile' on the bank statement On enterprise, this crashes when preparing the data to give to the reconciliation widget, as the write_off_vals key is not set properly by the call to _apply_rules. OPW 2367754 closes odoo/odoo#61265 X-original-commit: 1dd6199519b4ad5b5b17dfa17965ededcecb6da4 Related: odoo/enterprise#14563 Signed-off-by: Laurent Smet <smetl@users.noreply.github.com> Signed-off-by: oco-odoo <oco-odoo@users.noreply.github.com>
This commit is contained in:
@@ -317,7 +317,7 @@ class AccountReconcileModel(models.Model):
|
||||
lines_vals_list = []
|
||||
|
||||
for line in self.line_ids:
|
||||
currency_id = st_line.currency_id or st_line.journal_id.currency_id or self.company_id.currency_id
|
||||
currency_id = st_line.currency_id or st_line.journal_id.currency_id or self.company_id.currency_id
|
||||
if not line.account_id or currency_id.is_zero(residual_balance):
|
||||
return []
|
||||
|
||||
@@ -795,8 +795,10 @@ class AccountReconcileModel(models.Model):
|
||||
lines_vals_list = self._prepare_reconciliation(st_line, aml_ids=rslt['aml_ids'], partner=partner)
|
||||
|
||||
# A write-off must be applied if there are some 'new' lines to propose.
|
||||
if not lines_vals_list or any(not line_vals.get('id') for line_vals in lines_vals_list):
|
||||
write_off_lines_vals = list(filter(lambda x: 'id' not in x, lines_vals_list))
|
||||
if not lines_vals_list or write_off_lines_vals:
|
||||
rslt['status'] = 'write_off'
|
||||
rslt['write_off_vals'] = write_off_lines_vals
|
||||
|
||||
# Process auto-reconciliation. We only do that for the first two priorities, if they are not matched elsewhere.
|
||||
if lines_vals_list and priorities & {1, 3} and self.auto_reconcile:
|
||||
|
||||
@@ -712,3 +712,37 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||
self._check_statement_matching(matching_rule, {
|
||||
statement_line.id: {'aml_ids': (move_line_1 + move_line_2).ids, 'model': matching_rule, 'partner': statement_line.partner_id}
|
||||
}, statements=statement)
|
||||
|
||||
def test_inv_matching_with_write_off(self):
|
||||
self.rule_1.match_total_amount_param = 90
|
||||
self.bank_st.line_ids[1].unlink() # We don't need this one here
|
||||
statement_line = self.bank_st.line_ids[0]
|
||||
statement_line.write({
|
||||
'payment_ref': self.invoice_line_1.move_id.payment_reference,
|
||||
'amount': 90,
|
||||
})
|
||||
|
||||
# Test the invoice-matching part
|
||||
self._check_statement_matching(self.rule_1, {
|
||||
statement_line.id: {'aml_ids': self.invoice_line_1.ids, 'model': self.rule_1, 'partner': self.invoice_line_1.partner_id, 'status': 'write_off'},
|
||||
}, self.bank_st)
|
||||
|
||||
# Test the write-off part
|
||||
expected_write_off = {
|
||||
'balance': 10,
|
||||
'currency_id': False,
|
||||
'reconcile_model_id': self.rule_1.id,
|
||||
'account_id': self.current_assets_account.id,
|
||||
}
|
||||
|
||||
matching_result = self.rule_1._apply_rules(statement_line)
|
||||
|
||||
self.assertEqual(len(matching_result[statement_line.id].get('write_off_vals', [])), 1, "Exactly one write-off line should be proposed.")
|
||||
|
||||
full_write_off_dict = matching_result[statement_line.id]['write_off_vals'][0]
|
||||
to_compare = {
|
||||
key: full_write_off_dict[key]
|
||||
for key in expected_write_off.keys()
|
||||
}
|
||||
|
||||
self.assertDictEqual(expected_write_off, to_compare)
|
||||
|
||||
Reference in New Issue
Block a user