Files
Odoo-Modules/cleanup_duplicates.py
gsinghpal c66bdf5089 changes
2026-04-03 15:45:18 -04:00

74 lines
2.6 KiB
Python

import logging
_logger = logging.getLogger('cleanup_duplicates')
BSL = env['account.bank.statement.line'].sudo()
AML = env['account.move.line'].sudo()
AM = env['account.move'].sudo()
# All 64 duplicate statement line IDs (the second import set, 18703-18767)
dupe_ids = [
18703, 18704, 18705, 18706, 18707, 18708, 18709, 18710, 18711, 18712,
18713, 18714, 18715, 18716, 18717, 18718, 18719, 18720, 18721, 18722,
18723, 18724, 18725, 18726, 18727, 18728, 18729, 18730, 18731, 18732,
18733, 18734, 18735, 18736, 18737, 18738, 18739, 18740, 18741, 18742,
18743, 18744, 18745, 18746, 18747, 18748, 18749, 18750, 18751, 18752,
18753, 18754, 18755, 18756, 18757, 18758, 18759, 18760, 18761, 18762,
18763, 18764, 18766, 18767,
]
dupes = BSL.browse(dupe_ids)
print(f'Processing {len(dupes)} duplicate statement lines', flush=True)
reconciled_count = 0
unreconciled_count = 0
error_count = 0
for line in dupes:
move = line.move_id
if line.is_reconciled:
# Step 1: Un-reconcile — remove partial reconcile entries
# Find the statement line's AML and its partial reconciliations
st_aml = move.line_ids.filtered(lambda l: l.statement_line_id == line)
if st_aml:
# Find and remove partial reconcile entries
partials = env['account.partial.reconcile'].sudo().search([
'|',
('debit_move_id', 'in', st_aml.ids),
('credit_move_id', 'in', st_aml.ids),
])
if partials:
partials.unlink()
# Also check full reconcile
full_recs = st_aml.mapped('full_reconcile_id')
if full_recs:
full_recs.unlink()
reconciled_count += 1
# Step 2: Reset move to draft so we can delete it
try:
if move.state == 'posted':
move.button_draft()
# Step 3: Cancel and delete the move (which deletes the statement line too)
move.button_cancel()
move.with_context(force_delete=True).unlink()
unreconciled_count += 1
except Exception as e:
print(f' Error on line {line.id}: {e}', flush=True)
error_count += 1
env.cr.rollback()
continue
if unreconciled_count % 20 == 0:
env.cr.commit()
print(f' Progress: {unreconciled_count} deleted...', flush=True)
env.cr.commit()
print(f'DONE: {unreconciled_count} deleted, {reconciled_count} were reconciled, {error_count} errors', flush=True)
# Verify
remaining = BSL.search_count([('id', 'in', dupe_ids)])
print(f'Verification: {remaining} duplicate lines still exist (should be 0)', flush=True)