Class: Warranty::PublicRegistration

Inherits:
Object
  • Object
show all
Includes:
Service
Defined in:
app/services/warranty/public_registration.rb

Overview

Orchestrates a public warranty registration (Warranty Registration v2,
Phase 2): resolve the end-consumer Customer (RegistrantResolver),
persist the Warranty rows, claim the Uppy-uploaded warranty cards, and
notify staff (WarrantyMailer).

One submission can register several product lines at once (a matched order
with snow-melting mats AND a floor-heating roll) — pass
warranties_attributes with one attributes hash per product line and every
row is created in a single transaction. The single warranty_attributes
form remains for the manual (unmatched) flow.

result = Warranty::PublicRegistration.call(
order: order_or_nil,
registrant: { first_name:, last_name:, email:, phone:, street1:, ... },
warranties_attributes: [{ product_line:, installed_on:, ... }, ...],
upload_ids: [1, 2]
)

Defined Under Namespace

Classes: Result

Constant Summary collapse

PRODUCT_ATTR_KEYS =

Attribute keys that describe one registered unit — they build a
Warranty::Product; everything else in a hash is submission-level.
notes is the per-product "Additional Notes" panel field.

(%w[product_line product_model registered_skus serial_number line_item_id
   installation_type control_type term_years notes] +
Warranty::LINE_EXTRAS.values.flatten.map { |field| field[:key].to_s }).uniq.freeze

Instance Method Summary collapse

Methods included from Service

#attributes_used, #build_result, call, #logger

Methods included from Service::Initializer

#initialize

Instance Method Details

#callResult

Returns:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'app/services/warranty/public_registration.rb', line 52

def call
  attributes_list = Array(warranties_attributes.presence || [warranty_attributes]).map(&:to_h)
  return Result.new(success: false, error: 'Please provide warranty details.') if attributes_list.empty?

  resolution = nil
  warranty = nil
  error = nil
  already_registered = false

  # One outer transaction: a warranty validation failure must also roll
  # back a Customer the resolver just minted, or the registrant retries
  # the form against a half-created duplicate of themselves.
  ActiveRecord::Base.transaction do
    # The controller's one-shot check runs before this transaction, so
    # two concurrent submissions can both pass it — serialize on the
    # order row and recheck under the lock.
    if order
      order.lock!
      if Warranty.where(order_id: order.id).exists?
        already_registered = true
        raise ActiveRecord::Rollback
      end
    end

    resolution = resolve_registrant
    unless resolution.success
      error = resolution.error
      raise ActiveRecord::Rollback
    end

    begin
      warranty = persist_warranty!(attributes_list, resolution.customer)
    rescue ActiveRecord::RecordInvalid => e
      error = e.record.errors.full_messages.to_sentence
      warranty = nil
      raise ActiveRecord::Rollback
    end
  end

  return Result.new(success: false, already_registered: true) if already_registered
  return Result.new(success: false, error: error) if error

  WarrantyMailer.registered(warranty).deliver_later
  WarrantyMailer.confirmation(warranty).deliver_later

  Result.new(success: true, warranty: warranty,
             customer: resolution.customer, customer_created: resolution.created)
end