import logging from datetime import timedelta SL = env['poynt.settlement.line'].sudo() Invoice = env['account.move'].sudo() Payment = env['account.payment'].sudo() lines = SL.search([('state', '=', 'fetched'), ('action', '=', 'SALE')]) print(f'Unmatched SALE lines: {len(lines)}', flush=True) matched = 0 no_match = 0 for sl in lines: amount = sl.amount txn_date = sl.transaction_date.date() if sl.transaction_date else None if not txn_date or amount < 10: no_match += 1 continue # Strategy: Match against ALL invoices (not just open) by exact amount + close date # This catches invoices that were already paid by this terminal transaction invs = Invoice.search([ ('move_type', '=', 'out_invoice'), ('amount_total', '>=', amount - 0.50), ('amount_total', '<=', amount + 0.50), ('invoice_date', '>=', str(txn_date - timedelta(days=30))), ('invoice_date', '<=', str(txn_date + timedelta(days=5))), ], limit=5) if len(invs) == 1: sl.write({ 'partner_id': invs[0].partner_id.id, 'invoice_id': invs[0].id, 'state': 'matched', 'match_method': 'invoice_total', }) matched += 1 elif len(invs) > 1: # Multiple — try to pick the one closest in date best = min(invs, key=lambda i: abs((i.invoice_date - txn_date).days)) sl.write({ 'partner_id': best.partner_id.id, 'invoice_id': best.id, 'state': 'matched', 'match_method': 'invoice_total', }) matched += 1 else: no_match += 1 if (matched + no_match) % 100 == 0: env.cr.commit() env.cr.commit() print(f'Matched by invoice total: {matched}', flush=True) print(f'No match: {no_match}', flush=True) # Final stats print(f'\nFINAL STATE:', flush=True) for state in ['matched', 'fetched']: cnt = SL.search_count([('state', '=', state)]) print(f' {state}: {cnt}', flush=True) print(f' With invoice: {SL.search_count([("invoice_id", "!=", False)])}', flush=True)