from odoo import models, fields, api from odoo.exceptions import UserError class BankReconcileWizard(models.TransientModel): _name = 'bank.reconcile.wizard' _description = 'Bank Reconcile Wizard' bank_line_ids = fields.Many2many('account.bank.statement.line', string='Selected Bank Lines', readonly=True) journal_entry_id = fields.Many2one('account.move', string='Journal Entry to Reconcile', domain=[('state', '=', 'posted')]) journal_entry_line_id = fields.Many2one('account.move.line', string='Journal Entry Line to Reconcile', domain="[('move_id', '=', journal_entry_id), ('reconciled', '=', False)]") total_bank_line_amount = fields.Float(string='Total Bank Line Amount', compute='_compute_total_bank_line_amount', store=True) @api.onchange('journal_entry_id') def _onchange_journal_entry_id(self): """Reset journal entry line when journal entry changes""" if self.journal_entry_id: self.journal_entry_line_id = False else: self.journal_entry_line_id = False @api.depends('bank_line_ids') def _compute_total_bank_line_amount(self): """Compute total amount of selected bank lines""" for record in self: record.total_bank_line_amount = sum(line.amount for line in record.bank_line_ids) def action_reconcile(self): """Perform the reconciliation for each selected bank line""" if not self.journal_entry_id: raise UserError("Please select a journal entry to reconcile.") if not self.journal_entry_line_id: raise UserError("Please select a journal entry line to reconcile.") # Check if any of the selected bank lines are already reconciled for bank_line in self.bank_line_ids: if bank_line.move_id and bank_line.move_id.ref and 'Reconciliation:' in bank_line.move_id.ref: raise UserError(f"Bank statement line '{bank_line.ref}' has already been reconciled and cannot be reconciled again.") # 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) return {'type': 'ir.actions.act_window_close'} def _reconcile_single_line(self, bank_line, journal_entry_line): """Reconcile a single bank line with a journal entry line""" # 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': 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': 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, }) # 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 + move_line).reconcile() except: pass