Class: Www::LeadsController

Inherits:
BasePortalController show all
Defined in:
app/controllers/www/leads_controller.rb

Constant Summary

Constants included from Controllers::MasqueradeGuarded

Controllers::MasqueradeGuarded::DEFAULT_BLOCK_MESSAGE

Constants included from Controllers::AnalyticsEvents

Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY

Constants included from Controllers::ErrorRendering

Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES

Constants included from SeoHelper

SeoHelper::AWARDS, SeoHelper::CA_ADDRESS, SeoHelper::CA_BUSINESS_HOURS, SeoHelper::CA_CONTACT_POINT, SeoHelper::CA_CURRENCIES, SeoHelper::CA_DESCRIPTION, SeoHelper::CA_FOUNDING_DATE, SeoHelper::CA_GLOBAL_LOCATION_NUMBER, SeoHelper::CA_LEGAL_NAME, SeoHelper::CA_LOCAL_BUSINESS, SeoHelper::CA_ONLINE_STORE, SeoHelper::CA_RETURN_POLICY, SeoHelper::CA_SALES_DEPARTMENT, SeoHelper::CA_SERVICE_AREA, SeoHelper::CA_URL, SeoHelper::CA_VAT_ID, SeoHelper::CA_WAREHOUSE_DEPARTMENT, SeoHelper::CA_WAREHOUSE_HOURS, SeoHelper::COMPANY_EMAIL, SeoHelper::COMPANY_LOGO, SeoHelper::COMPANY_NAME, SeoHelper::COMPANY_SLOGAN, SeoHelper::EXPERTISE, SeoHelper::FAX_NUMBER, SeoHelper::GS1_COMPANY_PREFIX, SeoHelper::ISO6523_CODE, SeoHelper::PAYMENT_METHODS, SeoHelper::PHONE_NUMBER, SeoHelper::PRIMARY_NAICS, SeoHelper::REFUND_TYPE, SeoHelper::RETURN_FEES, SeoHelper::RETURN_METHOD, SeoHelper::RETURN_POLICY_CATEGORY, SeoHelper::SECONDARY_NAICS, SeoHelper::SOCIAL_PROFILES, SeoHelper::US_ADDRESS, SeoHelper::US_BUSINESS_HOURS, SeoHelper::US_CONTACT_POINT, SeoHelper::US_CURRENCIES, SeoHelper::US_DESCRIPTION, SeoHelper::US_FOUNDING_DATE, SeoHelper::US_GLOBAL_LOCATION_NUMBER, SeoHelper::US_IMAGE, SeoHelper::US_LEGAL_NAME, SeoHelper::US_LOCAL_BUSINESS, SeoHelper::US_ONLINE_STORE, SeoHelper::US_RETURN_POLICY, SeoHelper::US_SALES_DEPARTMENT, SeoHelper::US_SERVICE_AREA, SeoHelper::US_TAX_ID, SeoHelper::US_URL, SeoHelper::US_WAREHOUSE_DEPARTMENT, SeoHelper::US_WAREHOUSE_HOURS

Constants included from IconHelper

IconHelper::CUSTOM_ICON_MAP, IconHelper::CUSTOM_SVG_DIR, IconHelper::DEFAULT_FAMILY

Instance Method Summary collapse

Methods inherited from BasePortalController

#current_ability, #portal_party, #set_catalog, #set_webpack

Methods included from Controllers::MasqueradeGuarded

block_while_masquerading, #masquerade_blocks?

Methods inherited from ApplicationController

#account_impersonated?, #add_to_flash, #append_token, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #stamp_impersonation_context, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y

Methods included from Controllers::ReturnPathHandling

#check_for_return_path, #redirect_to_return_path_or_default

Methods included from Controllers::AnalyticsEvents

#consume_queued_analytics_events, #track_event

Methods included from Controllers::DeviceDetection

#device_detector, #is_ie?

Methods included from Controllers::SubdomainDetection

#is_crm_request?, #is_www_request?, #json_request?

Methods included from Controllers::TrackingDetection

#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?

Methods included from Controllers::AcceleratedFileSending

#send_file_accelerated, #send_upload_accelerated

Methods included from Controllers::ErrorRendering

#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #safe_referer_or_fallback

Methods included from Controllers::TurnstileVerification

#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!

Methods included from Controllers::CloudflareCaching

edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_session

Methods included from Controllers::Webpackable

#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?

Methods included from Controllers::Localizable

#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale

Methods included from Controllers::Authenticable

#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #authenticate_account_from_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak

Methods included from ApplicationHelper

#better_number_to_currency, #check_force_logout, #check_or_cross, #check_or_times, #error_messages, #general_disclaimer_on_product_installation_and_local_codes, #gridjs_from_html_table, #gridjs_table, #is_wy_ip, #line_break, #parent_layout, #pass_or_fail, #render_error_messages_list, #render_video_card, #resolved_auth_form_turbo_frame, #return_path_or, #safe_css_color, #set_return_path_if_present, #set_section_if_present, #tab_frame_id, #to_underscore, #track_page?, #turbo_section_wrapper, #turbo_tabs_request?, #url_on_same_domain_as_request, #widget_index_daily_focus_index_path, #working_hours?, #yes_or_no, #yes_or_no_highlighted, #yes_or_no_with_check_or_cross, #youtube_video

Methods included from UppyUploaderHelper

#file_uploader, #image_uploader, #large_file_uploader_s3, #lead_sketch_uploader, #rma_image_uploader, #rma_image_uploader_s3, #uppy_uploader, #video_uploader

Methods included from ImagesHelper

#image_asset_tag, #image_asset_url

Methods included from SeoHelper

#add_page_schema, #canada?, #company_social_links, #ensure_context_json, #json_ld_script_tag, #local_business_schema, #online_store_id, #online_store_schema, #page_main_entity, #page_main_entity_json, #render_auto_collection_page_schema, #render_collection_page_schema, #render_local_business_schema, #render_online_store_schema, #render_page_schemas, #render_page_video_schemas, #render_webpage_schema, #render_webpage_schema_with_collections, #usa?

Methods included from UrlsHelper

#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?

Methods included from IconHelper

#account_nav_icon, #fa_icon, #star_rating_html

Instance Method Details

#call_meObject



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/controllers/www/leads_controller.rb', line 148

def call_me
  check_current_time
  phone_number = PhoneNumber.parse_and_format(params[:phone_number])
  respond_to do |format|
    if @phone_chat_status
      if phone_number.nil?
        flash.now[:info] = 'Wrong Number? Please verify that the number you entered is correct and we\'ll try again.'
        format.turbo_stream { render partial: 'shared/flash' }
      else
        @context_user.phone = phone_number
        pbx = Phone::Pbx.instance
        result = begin
          pbx.place_call('616', phone_number, '1161')
        rescue StandardError
          false
        end
        if result == false
          flash.now[:info] = 'Sorry About That. Something went wrong with processing the call. Please try again in a few minutes.'
          format.turbo_stream { render partial: 'shared/flash' }
        else
          format.turbo_stream { render 'quote_request_call_me_success' }
        end
      end
    else
      flash.now[:info] = 'Service Unavailable Right Now. We\'re sorry but that service isn\'t available right now. You can try again during business hours or just send us an email.'
      format.turbo_stream { render partial: 'shared/flash' }
    end
  end
end

#complete_trade_applicationObject



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'app/controllers/www/leads_controller.rb', line 178

def complete_trade_application
  lead_notes = []
  lead_notes << "\r\nCUSTOMER WANTS TO BECOME A TRADE PRO"
  params[:tradepro_lead].each do |k, v|
    response = case v
               when '1'
                 'Yes'
               when '0'
                 'No'
               else
                 v
               end
    lead_notes << "#{k.to_s.titleize}: #{response}"
  end

  activity = @context_user.activities.open_activities.leads.last
  if activity.nil?
    @context_user.contacts.each do |co|
      activity = co.activities.open_activities.leads.last
    end
  end
  if activity.present?
    activity.notes += lead_notes.join("\r\n")
    activity.save
  end
  flash[:info] = 'Thank you. One of our experts will be in touch soon.'
  redirect_to cms_link('/')
end

#consultationObject



35
36
37
# File 'app/controllers/www/leads_controller.rb', line 35

def consultation
  check_current_time
end

#createObject



46
47
48
49
50
51
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/controllers/www/leads_controller.rb', line 46

def create
  backup_request
  lead_params = params.fetch(:lead, {}).to_h

  # Handle fallback file upload if present (when Uppy fails to initialize)
  # Native file input uses lead_fallback[sketch_drawings] instead of JSON upload IDs
  if params[:lead_fallback].present? && params[:lead_fallback][:sketch_drawings].present?
    fallback_files = Array(params[:lead_fallback][:sketch_drawings]).select { |f| f.respond_to?(:read) }
    if fallback_files.any?
      upload_ids = process_fallback_uploads(fallback_files)
      # Merge into lead_params as JSON array to match Uppy format
      lead_params['sketch_drawings'] = upload_ids.to_json if upload_ids.present?
    end
  end

  # Turnstile validates bot protection via before_action
  # SpamCheck validates contact points against known fraudulent customers
  is_fraud = SpamCheck.new.process(
    author_email: lead_params[:email].presence,
    phone_number: lead_params[:phone].presence,
    request: request
  )

  if is_fraud
    respond_to do |format|
      flash[:error] = 'There was an error submitting your request. Please call us at (800) 875-5285.'
      format.html { redirect_to cms_link('contact') }
      format.turbo_stream { render turbo_stream: turbo_stream.scroll_into_view("body", behavior: "smooth", block: "start") }
    end
    return
  end

  send_invite = false
  if params[:lang] == 'es'
    request.env['HTTP_REFERER'] ||= cms_link('/contact_es')
    js_render = 'lead_form_thank_you_es'
    # js_render_error kept for legacy paths; unused in this flow
    redirect_thank_you_url = '/contact_es/thank-you'
    error_notice = 'Ha ocurrido un error'
  elsif /trade/.match?(request.env['HTTP_REFERER'])
    redirect_thank_you_url = '/trade/thank-you'
    send_invite = true
  elsif /referral/.match?(request.env['HTTP_REFERER'])
    redirect_thank_you_url = '/referral-program/thank-you'
    send_invite = true
  elsif request.env['HTTP_REFERER'] =~ /support/ || request.env['HTTP_REFERER'] =~ %r{services/troubleshooting}
    redirect_thank_you_url = '/support/thank-you'
    send_invite = true
  else
    request.env['HTTP_REFERER'] ||= cms_link('/contact')
    redirect_thank_you_url = '/contact/thank-you'
  end
  js_render ||= 'lead_form_thank_you'
  # js_render_error kept for legacy paths; local variable no longer used
  error_notice ||= "Ooops, we couldn't process your request"
  @redirect_path = request.env['HTTP_REFERER']
  @lead = Lead.new(lead_params)
  save_result = @lead.save_to_user(@context_user.customer, send_invite)
  error_message = save_result.message unless save_result.success
  @frame_id = params[:frame_id].presence || 'contact-form-content'
  @support_case_reference = save_result.support_case_reference

  respond_to do |format|
    if error_message.blank?
      # Clear expiration_date for any uploaded files now attached via hidden field
      begin
        ids = begin
          JSON.parse(lead_params[:sketch_drawings].to_s)
        rescue StandardError
          []
        end
        Upload.where(id: ids).update_all(expiration_date: nil) if ids.present?
      rescue StandardError => _e
        # Non-blocking: if it fails, uploads will be cleaned up by expiration
      end

      # Record visit event for successful lead form submission
      record_lead_form_visit_event(lead_params)

      format.html { redirect_to_return_path_or_default cms_link(redirect_thank_you_url, nil, parameters: { cn: @context_user.reference_number, support_case_reference: save_result.support_case_reference }) }
      format.turbo_stream do
        if params[:modal_form] == 'true'
          render 'lead_form_modal_thank_you'
        else
          render js_render
        end
      end
    else
      validation_details = @lead&.errors&.any? ? " #{@lead.errors.full_messages.to_sentence}" : ""
      flash[:error] = "#{error_notice}: #{error_message}#{validation_details}"
      format.html { redirect_to @redirect_path }
      format.turbo_stream do
        if params[:modal_form] == 'true'
          render 'lead_form_modal_error'
        else
          render turbo_stream: turbo_stream.scroll_into_view("body", behavior: "smooth", block: "start")
        end
      end
    end
  end
end

#form_contentObject

GET /contact/form
Turbo Frame lazy-loaded content for modal contact form
Reduces page load by only loading form, turnstile, and uppy when modal opens



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'app/controllers/www/leads_controller.rb', line 18

def form_content
  @show_upload = params[:show_upload] != 'false'
  @business_focused = params[:business_focused] == 'true'
  @submit_label = params[:submit_label].presence || 'Send Message'
  @header_title = params[:header_title].presence
  @header_intro = params[:header_intro].presence
  @application_type = params[:application_type].presence
  @activity_type_id = params[:activity_type_id].presence
  @about_project = params[:about_project].presence
  @frame_id = params[:frame_id].presence || 'contact-form-content'

  # Track form opened event (user opened the modal)
  record_lead_form_opened_event

  render layout: false
end

#newObject



8
9
10
11
12
13
# File 'app/controllers/www/leads_controller.rb', line 8

def new
  check_current_time
  @quote_builder_url = params[:quote_builder_url]
  @quote_reference = params[:quote_reference]
  @phone_chat_status = false
end

#new_esObject



42
43
44
# File 'app/controllers/www/leads_controller.rb', line 42

def new_es
  check_current_time
end

#quoteObject



39
40
# File 'app/controllers/www/leads_controller.rb', line 39

def quote
end

#referral_thank_youObject



215
216
217
# File 'app/controllers/www/leads_controller.rb', line 215

def referral_thank_you
  render action: 'referral_thank_you'
end

#support_thank_youObject



211
212
213
# File 'app/controllers/www/leads_controller.rb', line 211

def support_thank_you
  render action: 'support_thank_you'
end

#thank_youObject



219
220
221
# File 'app/controllers/www/leads_controller.rb', line 219

def thank_you
  render action: 'lead_form_thank_you'
end

#thank_you_esObject



223
224
225
# File 'app/controllers/www/leads_controller.rb', line 223

def thank_you_es
  render action: 'lead_form_thank_you_es'
end

#trade_thank_youObject



207
208
209
# File 'app/controllers/www/leads_controller.rb', line 207

def trade_thank_you
  render action: 'tradepro_lead_form_thank_you'
end