Class: OnlineMigrations::DataMigrations::BackfillOpportunityParents
- Inherits:
-
OnlineMigrations::DataMigration
- Object
- OnlineMigrations::DataMigration
- OnlineMigrations::DataMigrations::BackfillOpportunityParents
- Defined in:
- lib/online_migrations/data_migrations/backfill_opportunity_parents.rb
Overview
Backfills Opportunity#parent_id on historical CRM opportunities that
are plausibly follow-ups to an earlier website-originated opportunity
for the same customer and project. The runtime equivalent lives on
the model as Opportunity#auto_link_to_web_parent (a before_create
callback); this migration applies the same rule retroactively to the
~110 pairs identified in the analysis attached to PR #750.
Match criteria
- Same
customer_id - Web opp's reception type ∈ IQ
- Web opp not in a terminal state (won / lost / abandoned / cancelled
/ untracked) — matchesOpportunity#open_opportunities - Web opp created within
LOOKBACK_DAYSdays BEFORE the CRM opp - Same
installation_postal_codeif both are set; otherwise a no-zip
web opp is the fallback. A different zip means a different project.
Constant Summary collapse
- BATCH_SIZE =
Batch size.
500- WEB_RECEPTION_TYPES =
Web reception types whose opps are eligible to be linked as parents.
%w[Online IQ].freeze
- LOOKBACK_DAYS =
Lookback window — a CRM opp is only considered a follow-up if the
web opp was created within this many days BEFORE the CRM opp. 180- TERMINAL_STATES =
States the web opp must NOT have reached for a CRM follow-up to be
considered a continuation of the same project. Mirrors the exclusion
list used by Opportunity#open_opportunities so the runtime auto-link
and the historical backfill apply the same rule. %w[won lost abandoned cancelled untracked].freeze
Instance Method Summary collapse
-
#collection ⇒ ActiveRecord::Batches::BatchEnumerator
CRM opportunities still eligible for parent backfill, batched.
-
#count ⇒ Integer
Total CRM opportunities still eligible for backfill.
-
#process(crm_opps) ⇒ void
Links each CRM opp in the batch to its candidate parent when the row is still unlinked.
Instance Method Details
#collection ⇒ ActiveRecord::Batches::BatchEnumerator
CRM opportunities still eligible for parent backfill, batched.
44 45 46 47 48 49 50 |
# File 'lib/online_migrations/data_migrations/backfill_opportunity_parents.rb', line 44 def collection Opportunity.where(opportunity_reception_type: "CRM", parent_id: nil, merged_into_id: nil) .where.not(customer_id: nil) .in_batches(of: BATCH_SIZE) end |
#count ⇒ Integer
Total CRM opportunities still eligible for backfill. Used by
online_migrations to render the progress bar.
76 77 78 79 80 81 82 |
# File 'lib/online_migrations/data_migrations/backfill_opportunity_parents.rb', line 76 def count Opportunity.where(opportunity_reception_type: "CRM", parent_id: nil, merged_into_id: nil) .where.not(customer_id: nil) .count end |
#process(crm_opps) ⇒ void
This method returns an undefined value.
Links each CRM opp in the batch to its candidate parent when the
row is still unlinked. The conditional update_all avoids
clobbering a row whose parent_id or merged_into_id was set by
the live before_create hook while this batch was in flight, and
also bypasses Auditable / callbacks — the correct semantic for a
backfill.
62 63 64 65 66 67 68 69 70 |
# File 'lib/online_migrations/data_migrations/backfill_opportunity_parents.rb', line 62 def process(crm_opps) crm_opps.each do |crm_opp| parent = candidate_parent_for(crm_opp) next unless parent Opportunity.where(id: crm_opp.id, parent_id: nil, merged_into_id: nil) .update_all(parent_id: parent.id, updated_at: Time.current) end end |