Class: Warranty::InstallationRecordMigrator

Inherits:
Object
  • Object
show all
Defined in:
app/services/warranty/installation_record_migrator.rb

Overview

Migrates the legacy Installation Records (the India-team keyed field-set on
Reads legacy room columns via id lookups, not the RoomConfiguration
associations — those are deprecated: true (:raise in dev/test) pending the
column drop, and this class must stay runnable for rollback.

room_configurations — system owner, installer/electrician parties, install
date, installed_items with serials + ohm/megohm readings, scanned cards)
onto the v2 Warranty model, so warranty data lives in one place
(doc/tasks/202608051319_INSTALLATION_RECORDS_TO_WARRANTIES.md).

ENRICH policy (Roman, 2026-08-06): when the resolved order/customer already
has a warranty, fill its blanks and append what's missing — never skip,
never violate one-warranty-per-order:

  • blank submission fields (installed_on, retailer_name) are filled
  • installer entries are APPENDED unless an entry with the same name+phone
    exists; entries carry installer_party_id, restoring the party linkage the
    v2 free-text flow lost
  • products are added only for product LINES the warranty doesn't already
    cover (guards against doubling the backfilled contact-form products)
  • the rooms' warranty-card uploads re-parent to the warranty

Created warranties get every mappable product: one Warranty::Product per
installed_item (serial + before/during/after readings + QC), falling back
to one bare product per installed product line when a room has lines but
no items. No confirmation email is sent either way — these customers
registered years ago.

Dry-run by default; every touched warranty is stamped with
details.migrated_from_room_ids for traceability and rollback.

Constant Summary collapse

READING_MAP =

Readings columns on installed_items → Warranty::Product detail keys.

{
  'before_ohm' => 'ohm_1', 'during_ohm' => 'ohm_2', 'after_ohm' => 'ohm_3',
  'before_mohm' => 'megohm_1', 'during_mohm' => 'megohm_2', 'after_mohm' => 'megohm_3',
  'qc_ohm' => 'qc_ohm', 'qc_mohm' => 'qc_megohm'
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dry_run: true, limit: nil, logger: Rails.logger) ⇒ InstallationRecordMigrator

Returns a new instance of InstallationRecordMigrator.



43
44
45
46
47
48
49
50
# File 'app/services/warranty/installation_record_migrator.rb', line 43

def initialize(dry_run: true, limit: nil, logger: Rails.logger)
  @dry_run = dry_run
  @limit = limit
  @logger = logger
  @stats = Hash.new(0)
  # [group_key, reason] pairs — the CSV the operator reviews.
  @skips = []
end

Instance Attribute Details

#skipsObject (readonly)

Returns the value of attribute skips.



41
42
43
# File 'app/services/warranty/installation_record_migrator.rb', line 41

def skips
  @skips
end

#statsObject (readonly)

Returns the value of attribute stats.



41
42
43
# File 'app/services/warranty/installation_record_migrator.rb', line 41

def stats
  @stats
end

Instance Method Details

#callHash

Returns the summary counts.

Returns:

  • (Hash)

    the summary counts



53
54
55
56
57
58
59
60
61
62
63
# File 'app/services/warranty/installation_record_migrator.rb', line 53

def call
  groups = RoomConfiguration.where.not(system_owner_id: nil)
                            .order(:id)
                            .group_by { |rc| [rc.system_owner_id, rc.opportunity_id || "room-#{rc.id}"] }
  groups = groups.first(@limit).to_h if @limit
  @logger.info "[InstallationRecordMigrator] #{groups.size} groups (dry_run=#{@dry_run})"

  groups.each { |key, rooms| migrate_group(key, rooms) }
  @logger.info "[InstallationRecordMigrator] Done: #{@stats.inspect}"
  @stats
end