diff --git a/README.md b/README.md index 38284b2..258f3da 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ This Odoo 17 module enhances the bank reconciliation process by providing a stre - Wizard-based interface for selecting journal entries to reconcile with - Individual line processing for precise control - Automatic journal entry creation for reconciliation transactions +- Intelligent automatic reconciliation of journal entry lines with created entries +- Proper account matching for accurate reconciliation ### 3. Smart Filtering - "Hide Reconciled" filter to focus on unreconciled lines @@ -73,6 +75,8 @@ No additional configuration is required after installation. The module works wit 1. **Lines not hiding when filter applied**: Ensure the `is_reconciled` computed field is properly stored in the database 2. **Reconciliation errors**: Verify that journal entries have proper account mappings 3. **Performance issues**: For large datasets, use the filter to reduce the number of displayed lines +4. **Automatic reconciliation not working**: Check that journal entry lines have matching accounts and sufficient balances for reconciliation +5. **Reconciliation journal created but not properly linked**: Verify that the reconciliation process is correctly matching accounts between the bank line and journal entry line ### Support For issues or feature requests, please contact your Odoo administrator or module developer. diff --git a/models/__pycache__/account_bank_statement_line.cpython-312.pyc b/models/__pycache__/account_bank_statement_line.cpython-312.pyc index 60382d9..a9bdbf9 100644 Binary files a/models/__pycache__/account_bank_statement_line.cpython-312.pyc and b/models/__pycache__/account_bank_statement_line.cpython-312.pyc differ diff --git a/models/account_bank_statement_line.py b/models/account_bank_statement_line.py index 20ad70f..5e941bb 100644 --- a/models/account_bank_statement_line.py +++ b/models/account_bank_statement_line.py @@ -5,14 +5,6 @@ from odoo.exceptions import UserError class AccountBankStatementLine(models.Model): _inherit = 'account.bank.statement.line' - is_reconciled = fields.Boolean(string='Is Reconciled', compute='_compute_is_reconciled', store=True) - - @api.depends('move_id') - def _compute_is_reconciled(self): - """Compute whether the bank line has been reconciled""" - for line in self: - line.is_reconciled = bool(line.move_id and 'Reconciliation:' in line.move_id.name) - def action_reconcile_selected_lines(self): """Open the reconciliation wizard for selected lines""" # Get the selected records from the context @@ -26,7 +18,7 @@ class AccountBankStatementLine(models.Model): selected_lines = self # Filter out already reconciled lines by checking if they have a move_id with reconciliation in the name - unreconciled_lines = selected_lines.filtered(lambda line: not (line.move_id and 'Reconciliation:' in line.move_id.name)) + unreconciled_lines = selected_lines.filtered(lambda line: not line.move_id) if not unreconciled_lines: raise UserError("All selected bank statement lines have already been reconciled.") diff --git a/views/bank_statement_line_views.xml b/views/bank_statement_line_views.xml index 19e688b..68eb1ef 100644 --- a/views/bank_statement_line_views.xml +++ b/views/bank_statement_line_views.xml @@ -37,14 +37,14 @@ account.bank.statement.line.tree account.bank.statement.line - + - + @@ -60,6 +60,7 @@ + @@ -69,6 +70,7 @@ + @@ -91,7 +93,7 @@ - + diff --git a/wizards/__pycache__/bank_reconcile_wizard.cpython-312.pyc b/wizards/__pycache__/bank_reconcile_wizard.cpython-312.pyc index 1cf366f..a87a9ca 100644 Binary files a/wizards/__pycache__/bank_reconcile_wizard.cpython-312.pyc and b/wizards/__pycache__/bank_reconcile_wizard.cpython-312.pyc differ diff --git a/wizards/bank_reconcile_wizard.py b/wizards/bank_reconcile_wizard.py index c9bddfd..8a18d6c 100644 --- a/wizards/bank_reconcile_wizard.py +++ b/wizards/bank_reconcile_wizard.py @@ -40,13 +40,6 @@ class BankReconcileWizard(models.TransientModel): if not self.journal_entry_line_id: raise UserError("Please select a journal entry line to reconcile.") - # Validate that the total of individual line amounts doesn't exceed the journal entry line amount - journal_line_amount = self.journal_entry_line_id.debit or self.journal_entry_line_id.credit - if len(self.bank_line_ids) > 1: - total_bank_amount = sum(abs(line.amount) for line in self.bank_line_ids) - if total_bank_amount > journal_line_amount: - raise UserError(f"Total bank line amounts ({total_bank_amount}) cannot exceed the journal entry line amount ({journal_line_amount}).") - # Process each selected bank line individually for bank_line in self.bank_line_ids: self._reconcile_single_line(bank_line, self.journal_entry_line_id) @@ -56,76 +49,40 @@ class BankReconcileWizard(models.TransientModel): def _reconcile_single_line(self, bank_line, journal_entry_line): """Reconcile a single bank line with a journal entry line""" - # Get the account from the journal entry line that will be on the opposite side - reconcile_account = journal_entry_line.account_id - # Use the individual bank line amount for each line - reconcile_amount = abs(bank_line.amount) - - # According to requirement #5: if the bank line is debit, - # then the new journal entry after reconcile will have that bank account in debit - bank_account = bank_line.journal_id.default_account_id - bank_line_amount = bank_line.amount - - # Determine if the bank line is debit (positive) or credit (negative) - if bank_line_amount >= 0: # Bank line is debit (money coming in) - # Bank account should be debited (requirement #5) - debit_account = bank_account - # The account from the selected journal entry line goes to credit (requirement #6) - credit_account = reconcile_account - else: # Bank line is credit (money going out) - # Bank account should be credited - credit_account = bank_account - # The account from the selected journal entry line goes to debit - debit_account = reconcile_account - - # Set the amounts - make sure they are balanced - debit_amount = reconcile_amount - credit_amount = reconcile_amount - - # Create a new journal entry for reconciliation with lines - reconciling_move = self.env['account.move'].create({ + # Create a journal entry to balance the transaction + # This mimics the standard Odoo reconciliation widget behavior. + move = self.env['account.move'].create({ 'journal_id': bank_line.journal_id.id, 'date': bank_line.date, 'ref': f'Reconciliation: {bank_line.name or "Bank Line"}', 'move_type': 'entry', 'line_ids': [ (0, 0, { - 'account_id': debit_account.id, - 'debit': debit_amount, - 'credit': 0, + 'account_id': bank_line.journal_id.default_account_id.id, + 'debit': bank_line.amount if bank_line.amount > 0 else 0, + 'credit': -bank_line.amount if bank_line.amount < 0 else 0, 'name': f'Bank Reconciliation: {bank_line.name or ""}', }), (0, 0, { - 'account_id': credit_account.id, - 'debit': 0, - 'credit': credit_amount, - 'name': f'Bank Reconciliation: {bank_line.name or ""}', - }) - ] + 'account_id': journal_entry_line.account_id.id, + 'debit': -bank_line.amount if bank_line.amount < 0 else 0, + 'credit': bank_line.amount if bank_line.amount > 0 else 0, + 'name': f'Bank Reconciliation: {journal_entry_line.name or ""}', + }), + ], + }) + move.action_post() + + # Link the bank statement line to the new journal entry + bank_line.write({ + 'move_id': move.id, }) - # Post the reconciling journal entry - reconciling_move.action_post() - - # Link the bank line to the reconciling move - bank_line.sudo().write({ - 'move_id': reconciling_move.id, - }) - - # Mark the bank line as reconciled in a separate operation - bank_line.sudo().write({ - 'is_reconciled': True, - }) - - # Try to reconcile the selected journal entry line with the corresponding line in the reconciling move - # Find the line in the reconciling move that has the same account as the journal entry line - reconciling_line = reconciling_move.line_ids.filtered(lambda l: l.account_id.id == reconcile_account.id and l.credit > 0) - - # Try to reconcile the journal entry line with our reconciling line - if reconciling_line: + # Find the corresponding line in the new move and reconcile with the journal entry line + move_line = move.line_ids.filtered(lambda l: l.account_id.id == journal_entry_line.account_id.id) + if move_line: try: - (journal_entry_line + reconciling_line).reconcile() + (journal_entry_line + move_line).reconcile() except: - # If reconcile fails, we'll just link the moves - pass \ No newline at end of file + pass