fix(fusion_accounting_followup): seeded levels + migration idempotency

- test_create_minimal/negative_delay used sequence=1, which now collides
  with the seeded Friendly Reminder level. Use sequences 901/902.
- migration backfill: search by name (not raw seq) for idempotency,
  allocate sequence as max(existing)+1 to avoid both seed clashes and
  within-batch collisions when Enterprise has duplicate sequence values.

Made-with: Cursor
This commit is contained in:
gsinghpal
2026-04-19 21:33:26 -04:00
parent d0a912b1da
commit 8eb4b8dc6c
2 changed files with 25 additions and 17 deletions

View File

@@ -37,31 +37,38 @@ class FusionMigrationWizard(models.TransientModel):
result['errors'].append(f"Enterprise search failed: {e}")
return result
# Pick a starting offset that doesn't clash with anything already in
# fusion_followup_level (seeded defaults at 1..3 plus any prior
# migration runs). We allocate a unique sequence per Enterprise line
# by max(existing) + 1, ensuring idempotency + within-batch uniqueness.
existing_max = max(FusionLevel.search([]).mapped('sequence') or [100])
next_seq = max(existing_max + 1, 101)
# Map Enterprise tone-ish fields to ours
for ee in ee_records:
try:
# Idempotency: skip if a level with same sequence + name already exists
seq = getattr(ee, 'sequence', None) or 50
name = getattr(ee, 'name', None) or f"Migrated Level {seq}"
existing = FusionLevel.search([
('sequence', '=', seq),
('name', '=', name),
], limit=1)
raw_seq = getattr(ee, 'sequence', None) or 50
name = getattr(ee, 'name', None) or f"Migrated Level {raw_seq}"
# Idempotency: skip if a level with same name was already
# backfilled in a prior migration run.
existing = FusionLevel.search([('name', '=', name)], limit=1)
if existing:
result['skipped'] += 1
continue
delay = getattr(ee, 'delay', None) or getattr(ee, 'delay_days', 7)
# Enterprise tone heuristic: scale by sequence
tone = 'gentle' if seq <= 1 else 'firm' if seq <= 2 else 'legal'
tone = 'gentle' if raw_seq <= 1 else 'firm' if raw_seq <= 2 else 'legal'
FusionLevel.create({
'name': name,
'sequence': seq + 100, # offset so we don't clash with seeded defaults
'delay_days': delay,
'tone': tone,
'active': True,
})
with self.env.cr.savepoint():
FusionLevel.create({
'name': name,
'sequence': next_seq,
'delay_days': delay,
'tone': tone,
'active': True,
})
next_seq += 1
result['created'] += 1
except Exception as e:
result['errors'].append(f"Line {ee.id}: {e}")