import logging AML = env['account.move.line'].sudo() BSL = env['account.bank.statement.line'].sudo() company_partner_id = env.company.partner_id.id # RBC Visa (28) incoming CC payments - match against Outstanding Payments (77 + 494) cc_lines = BSL.search([ ('journal_id', '=', 28), ('is_reconciled', '=', False), ('amount', '>', 0), ('company_id', '=', env.company.id), ]) # Filter to CC payment patterns only transfer_lines = cc_lines.filtered( lambda l: any(p in (l.payment_ref or '').lower() for p in [ 'payment - thank you', 'credit card payment', 'rbc credit card', 'payment to credit card', 'paiement - merci', 'pay rbc credit card', 'credit card pay' ]) ) print(f'RBC Visa incoming CC payments: {len(transfer_lines)}', flush=True) # Get outstanding entries on accounts 77 and 494 all_outstanding = AML.search([ ('account_id', 'in', [77, 494]), ('partner_id', '=', company_partner_id), ('reconciled', '=', False), ('amount_residual', '>', 0), ], order='date asc') # Index by amount by_amount = {} for o in all_outstanding: by_amount.setdefault(round(o.amount_residual, 2), []).append(o) print(f'Outstanding entries available: {len(all_outstanding)}', flush=True) reconciled = 0 no_match = 0 used_ids = set() for line in sorted(transfer_lines, key=lambda l: l.move_id.date): amount = round(line.amount, 2) candidates = [c for c in by_amount.get(amount, []) if c.id not in used_ids] if not candidates: no_match += 1 continue # Pick closest date best = min(candidates, key=lambda c: abs((c.date - line.move_id.date).days)) try: line.partner_id = company_partner_id line.set_line_bank_statement_line(best.ids) used_ids.add(best.id) reconciled += 1 except Exception as e: if reconciled < 3: print(f' Error: line {line.id} (${amount}): {e}', flush=True) if reconciled % 50 == 0 and reconciled > 0: env.cr.commit() env.cr.commit() print(f'Reconciled: {reconciled}', flush=True) print(f'No outstanding match: {no_match}', flush=True) # For remaining with no outstanding entry, create writeoff models remaining = BSL.search_count([ ('journal_id', '=', 28), ('is_reconciled', '=', False), ('amount', '>', 0), ]) print(f'RBC Visa remaining incoming unreconciled: {remaining}', flush=True)