75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
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)
|