import logging from datetime import timedelta AML = env['account.move.line'].sudo() # Outstanding Receipts (493) has: # - CREDITS from Elavon bank deposits (reconcile model posted them) # - DEBITS from Poynt customer payments (we just created them) # These need to be matched against each other # Get all unreconciled lines on account 493 credits = AML.search([ ('account_id', '=', 493), ('reconciled', '=', False), ('balance', '<', 0), # Credits (Elavon deposits) ('parent_state', '=', 'posted'), ], order='date asc') debits = AML.search([ ('account_id', '=', 493), ('reconciled', '=', False), ('balance', '>', 0), # Debits (Poynt payments + other) ('parent_state', '=', 'posted'), ], order='date asc') print(f'Unreconciled on Outstanding Receipts (493):', flush=True) print(f' Credits (Elavon deposits etc): {len(credits)}, total: {sum(c.balance for c in credits):.2f}', flush=True) print(f' Debits (Poynt payments etc): {len(debits)}, total: {sum(d.balance for d in debits):.2f}', flush=True) # Strategy: match credits and debits by exact amount + close date # Build index of debits by amount from collections import defaultdict debit_by_amount = defaultdict(list) for d in debits: debit_by_amount[round(d.balance, 2)].append(d) matched = 0 used_debit_ids = set() for credit in credits: credit_amount = round(abs(credit.balance), 2) candidates = [d for d in debit_by_amount.get(credit_amount, []) if d.id not in used_debit_ids] if not candidates: continue # Pick closest date best = min(candidates, key=lambda d: abs((d.date - credit.date).days)) gap = abs((best.date - credit.date).days) # Match if within 30 days if gap <= 30: try: (credit + best).reconcile() used_debit_ids.add(best.id) matched += 1 except Exception as e: if matched < 3: print(f' Error matching {credit.id} + {best.id}: {e}', flush=True) if matched % 100 == 0 and matched > 0: env.cr.commit() print(f' Progress: {matched} matched', flush=True) env.cr.commit() print(f'\nMatched: {matched} pairs on Outstanding Receipts', flush=True) # Check remaining remaining = AML.search_count([ ('account_id', '=', 493), ('reconciled', '=', False), ('parent_state', '=', 'posted'), ]) print(f'Remaining unreconciled on 493: {remaining}', flush=True)