Class: RoomConfigurationsController

Inherits:
CrmController show all
Includes:
Controllers::Attachable, Controllers::HeatLoss, Controllers::RequireTurboFrame, Controllers::RoomsTab, Controllers::Workflowable
Defined in:
app/controllers/room_configurations_controller.rb

Overview

Controller: room configurations (heat-loss rooms attached to a quote,
order, or opportunity — floor plans, installation plans, and line items).

Constant Summary collapse

TAB_ACTIONS =

Tab fragments never render standalone — non-frame hits redirect to show ?tab=.

%i[tab_alerts tab_main tab_tickets tab_revision].freeze

Constants included from Controllers::Attachable

Controllers::Attachable::PUBLICATIONS_PER_PAGE

Constants included from HeatLossPathsHelper

HeatLossPathsHelper::HEAT_LOSS_ACTIONS

Constants included from Controllers::ReferenceFindable

Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS

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

Instance Method Summary collapse

Methods included from Controllers::Workflowable

#render_workflow_error_stream, #render_workflow_success_stream, #workflow_action, #workflow_action_complete

Methods included from Controllers::Attachable

#attach, #publication_modal, #remove_attachment, #search_library

Methods included from Controllers::RequireTurboFrame

require_in_pane_tab_frames, require_turbo_frame

Methods included from Controllers::HeatLoss

#ceiling_heat_loss_details, #complete_ceiling_heat_loss_details, #complete_doors_heat_loss_details, #complete_exterior_walls_heat_loss_details, #complete_heat_loss_info, #complete_room_heat_loss_details, #complete_skylights_heat_loss_details, #complete_under_floor_heat_loss_details, #complete_windows_heat_loss_details, #doors_heat_loss_details, #dupe_door_heat_loss_details, #dupe_exterior_wall_heat_loss_details, #dupe_skylight_heat_loss_details, #dupe_window_heat_loss_details, #enter_heat_loss_info, #exterior_walls_heat_loss_details, #heat_loss_details_summary, #projects_path_for, #remove_door_heat_loss_details, #remove_exterior_wall_heat_loss_details, #remove_skylight_heat_loss_details, #remove_window_heat_loss_details, #room_heat_loss_details, #set_ceiling_variables, #set_doors_variables, #set_exterior_walls_variables, #set_skylights_variables, #set_under_floor_variables, #set_windows_variables, #show_heat_loss, #show_heat_loss_path_for, #skylights_heat_loss_details, #under_floor_heat_loss_details, #update_ceiling_type, #update_door_type, #update_exterior_wall_type, #update_under_floor_type, #update_window_type, #windows_heat_loss_details

Methods included from HeatLossPathsHelper

#crm_request?, #enter_heat_loss_info_path_for_room, #format_errors_as_list, #heat_loss_path, #hl_btn_submit_class, #hl_card_class, #hl_card_col_class, #hl_card_content_class, #hl_card_header_class, #hl_card_title_class, #room_path_for_room, #show_heat_loss_path_for_room

Methods inherited from CrmController

#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie, #touch_employee_last_seen

Methods inherited from ApplicationController

#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #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?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #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, #registration_lead_type, #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::TurboSafeRedirect

#redirect_to

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, #render_unpermitted_parameters, #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_edge_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!, #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 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?

Instance Method Details

#append_cable_spacing_to_snow_melt_mats(heating_system_product_line_options) ⇒ Array<Array>

Relabels snow-melt-mat product line options with the product line's name.

Parameters:

  • heating_system_product_line_options (Array<Array>)

    [label, id] pairs

Returns:

  • (Array<Array>)

    the same pairs, relabeled for snow-melt-mat product lines



481
482
483
# File 'app/controllers/room_configurations_controller.rb', line 481

def append_cable_spacing_to_snow_melt_mats(heating_system_product_line_options)
  heating_system_product_line_options.map { |n, v| v && (pl = ProductLine.find(v)).snow_melt_mat? ? [pl.name, v] : [n, v] }
end

#calculate_line_itemsvoid

This method returns an undefined value.

Loads material alerts for the room's line-item recalculation confirmation.



253
254
255
# File 'app/controllers/room_configurations_controller.rb', line 253

def calculate_line_items
  @material_alerts = @room_configuration.get_material_alerts
end

#clearObject

Clears a draft room and remove all line items



99
100
101
102
103
104
105
106
107
108
# File 'app/controllers/room_configurations_controller.rb', line 99

def clear
  if @room_configuration.draft?
    @room_configuration.line_items.destroy_all
    @room_configuration.save
    flash[:info] = 'Room line items were cleared out'
  else
    flash[:error] = 'Room must be in draft stage to allow clearing'
  end
  redirect_to_return_path_or_default room_configuration_path(@room_configuration)
end

#complete_calculate_line_itemsvoid

This method returns an undefined value.

Applies submitted room attributes and resynchronizes the room's line items.



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'app/controllers/room_configurations_controller.rb', line 260

def complete_calculate_line_items
  if @room_configuration.orders.room_not_pickable.empty?
    @room_configuration.update(params[:room_configuration])
    # puts "complete_calculate_line_items: res: #{res}"
    @room_configuration.apply_iq_room_line_item_options
    @room_configuration.reload
    @room_configuration.synchronize_lines(nil, true)
    # invalidate old ones and add new ones
    @room_configuration.invalidate_design_guidelines
    design_guidelines = params[:design_guideline_uploads] || {}
    design_guidelines.each_value do |p|
      @room_configuration.uploads << Upload.uploadify(p[:upload_path], p[:category])
    end
  else
    flash[:error] = "Could not modify room items: room is in these orders: #{@room_configuration.orders.room_not_pickable.map(&:reference_number).join(', ')}"
  end
  redirect_to_return_path_or_default(room_configuration_path(@room_configuration))
end

#complete_redesignObject

POST /customers/1/opportunities/1/room_configurations/1/complete_redesign



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'app/controllers/room_configurations_controller.rb', line 370

def complete_redesign
  @redesign = true
  @original_rc = RoomConfiguration.find(params.expect(:id))
  originating_quote_id = params[:originating_quote_id].presence || params[:quote_id].presence
  @new_rc = @room_configuration.deep_dup
  @new_rc.zones.destroy_all # we get zones via params, not dup
  @new_rc = assign_param(@new_rc, params, true)
  # Capture the quotes the user selected on the redesign form, then save the
  # new room with no HABTM joins. We perform the swap from the Quote side
  # below so the `before_remove` / `before_add` callbacks on `MultiRoom` run
  # (destroying the original room's line items, then syncing the new room's).
  desired_quote_ids = Array(@new_rc.quote_ids).map(&:to_i)
  desired_quote_ids << originating_quote_id.to_i if originating_quote_id.present?
  desired_quote_ids.uniq!
  @new_rc.quote_ids = []

  if params[:next_step] == 'send_to_engineering'
    @new_rc.send_to_engineering
  # elsif params[:next_step] == 'skip_engineering'
  #   @new_rc.revert_to_draft unless @new_rc.draft?
  else # implies just save
    @new_rc.save
  end

  if @new_rc.errors.empty?
    swap_room_on_quotes!(desired_quote_ids)

    if originating_quote_id.present?
      flash[:info] = "Replaced #{@original_rc.reference_number} with #{@new_rc.reference_number}."
      redirect_to rooms_quote_path(originating_quote_id)
    else
      redirect_to_return_path_or_default(room_configuration_path(@new_rc))
    end
  else
    @new_rc.errors.full_messages.each do |m|
      @room_configuration.errors.add(:base, m)
    end
    @room_configuration.attributes = @new_rc.attributes
    @new_rc.destroy unless @new_rc.new_record? # Cleanup we have errors to deal with

    set_edit_variables
    render :redesign, status: :unprocessable_content
  end
end

#copyvoid

This method returns an undefined value.

Renders the form for copying a room configuration to a different opportunity.



211
212
213
214
215
# File 'app/controllers/room_configurations_controller.rb', line 211

def copy
  @room_configuration = RoomConfiguration.find(params.expect(:id))
  @opportunity = @room_configuration.opportunity
  @customer = @opportunity.customer
end

#createObject

PUT /customers/1/opportunities/1/room_configurations



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'app/controllers/room_configurations_controller.rb', line 190

def create
  @room_configuration = @opportunity.room_configurations.build
  @room_configuration = assign_param(@room_configuration, params)
  @room_configuration.name = @opportunity.next_room_name({ room_base_name: @room_configuration.name, room_type: @room_configuration.room_type, heating_system_product_line: @room_configuration.heating_system_product_line })
  @room_configuration.has_new_floorplan = false
  @room_configuration.currency = @customer.store.currency
  @room_configuration.reception_date = Date.current
  @room_configuration.insulation_surface ||= @room_configuration.rectangular_area # this is only for CRM rooms to set insulated area to room dimensions fallback on create

  set_room_attributes_for_next_step
  if @room_configuration.save
    handle_next_step
  else
    set_edit_variables(true)
    render action: :new, status: :unprocessable_content
  end
end

#destroyObject

DELETE /customers/1/opportunities/1/room_configurations/1



310
311
312
313
314
315
# File 'app/controllers/room_configurations_controller.rb', line 310

def destroy
  quotes = @room_configuration.quotes.dup
  @opportunity.room_configurations.destroy(@room_configuration)
  quotes.each(&:request_plans_or_complete)
  redirect_to opportunity_path(@opportunity)
end

#destroy_attachmentvoid

This method returns an undefined value.

Deletes the given upload.



328
329
330
331
332
# File 'app/controllers/room_configurations_controller.rb', line 328

def destroy_attachment
  upload = Upload.find(params.expect(:id))
  upload.destroy
  redirect_to customers_path
end

#do_copyvoid

This method returns an undefined value.

Copies the room configuration to the opportunity selected on copy.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'app/controllers/room_configurations_controller.rb', line 220

def do_copy
  if (opportunity_id = params.dig(:copy, :opportunity_id)).present?
    @opportunity = Opportunity.find(opportunity_id)
  end

  if @opportunity
    begin
      res = RoomConfiguration::Copier.new(RoomConfiguration.where(id: @room_configuration.id)).copy_to(@opportunity)
      new_room_configuration_id = res.room_copy_results.values.first
      flash[:info] = 'Room was successfully copied'
      redirect_to room_configuration_path(new_room_configuration_id)
    rescue StandardError => e
      flash[:error] = "Unable to copy room: #{e}"
      redirect_back_or_to(root_path)
    end
  else
    flash[:error] = 'Invalid opportunity selected'
    redirect_back_or_to(root_path)
  end
end

#download_attachmentvoid

This method returns an undefined value.

Streams the given upload as a download.



320
321
322
323
# File 'app/controllers/room_configurations_controller.rb', line 320

def download_attachment
  upload = Upload.find(params.expect(:id))
  send_upload_accelerated(upload, download: true)
end

#editObject

GET /customers/1/opportunities/1/room_configurations/1/edit



156
157
158
# File 'app/controllers/room_configurations_controller.rb', line 156

def edit
  set_edit_variables(true)
end

#edit_installation_plansvoid

This method returns an undefined value.

Renders the installation plans editor, defaulting the floorplanner,
designer, labeler, and QC employees to the current user.



144
145
146
147
148
149
150
151
152
153
# File 'app/controllers/room_configurations_controller.rb', line 144

def edit_installation_plans
  authorize!(:update_installation_plans, @room_configuration)
  # redirect_to @room_configuration, alert: "Installation plans cannot be edited on completed rooms." if @room_configuration.complete?
  @room_configuration.floorplanner_employee_id = @context_user.id unless @room_configuration.floorplanner_employee
  @room_configuration.designer_employee_id = @context_user.id unless @room_configuration.designer_employee
  @room_configuration.labeler_employee_id = @context_user.id unless @room_configuration.labeler_employee
  @room_configuration.installation_plan_qc_employee_id = @context_user.id unless @room_configuration.installation_plan_qc_employee
  # @room_configuration.legacy_installation_plan = false
  @room_configuration.plan_created_at ||= Time.current
end

#edit_nameObject

GET /customers/1/opportunities/1/room_configurations/1/edit_name



161
162
163
# File 'app/controllers/room_configurations_controller.rb', line 161

def edit_name
  load_room
end

#electrical_planvoid

This method returns an undefined value.

Streams the room's electrical plan PDF.



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/controllers/room_configurations_controller.rb', line 113

def electrical_plan
  respond_to do |format|
    format.pdf do
      # set the heating system in case they're previewing and it's not set yet
      @room_configuration.set_quoted_heating_system_product_line if @room_configuration.quoted_heating_system_pl_id.nil?

      send_data @room_configuration.generate_electrical_plan_pdf([], true),
                filename: @room_configuration.electrical_file_name,
                type: 'application/pdf',
                disposition: 'inline'
    end
  end
end

#fetch_room_configuration_options(set_initial_name = false) ⇒ void

This method returns an undefined value.

Runs GetRoomOptions for the current room and sets the resulting
environment/floor/heating-system/voltage/cable-spacing option variables
used by the room form's dynamic fields.

Parameters:

  • set_initial_name (Boolean) (defaults to: false)

    whether to derive the room's name from
    the fetched options (new rooms only; redesigned rooms keep a locked name)



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'app/controllers/room_configurations_controller.rb', line 440

def fetch_room_configuration_options(set_initial_name = false)
  logger.debug 'fetch_room_configuration_options'
  # here only new rooms get the dynamic room name update, otherwise treat redesigned rooms as having locked room names
  @update_room_name = (set_initial_name == true) || (params[:room_type_id_changed] == '1')
  @update_room_name = false if params[:room_name_touched] == '1'
  result = GetRoomOptions.new.process(@customer&.store&.id || 1, @room_configuration,
                                      { room_params: params[:room_configuration], floor_type_id_changed: params[:floor_type_id_changed], update_room_name: @update_room_name, installation_postal_code: @installation_postal_code, include_blank_heating_system: true, room_quoting_method: params[:room_quoting_method] || 'engineering' })
  @room_type = result.room_type
  @environment = result.environment
  @sub_floor_type_options = result.sub_floor_type_options
  @sub_floor_type = result.sub_floor_type
  @sub_floor_type_id = result.sub_floor_type_id
  @floor_type_options = result.floor_type_options
  @floor_type = result.floor_type
  @floor_type_id = result.floor_type_id
  @heating_system_product_line_options = append_cable_spacing_to_snow_melt_mats(result.heating_system_product_line_options)
  @heating_system_product_line = result.heating_system_product_line
  @heating_system_product_line_id = result.heating_system_product_line_id
  @voltage_options = result.voltage_options
  @voltage_id = result.voltage_id
  @require_cable_spacing = result.require_cable_spacing
  @cable_spacing_options = result.cable_spacing_options
  @cable_spacing = result.cable_spacing
  @default_cable_spacings = HeatingElementProductLineOption.default_cable_spacings
  @recommended_cable_spacings = HeatingElementProductLineOption.default_cable_spacings(@installation_postal_code, @sub_floor_type, @floor_type)
  @coverage_state = result.coverage_state
  @all_alternate_heplo_options = result.all_alternate_heplo_options
  @alternate_heplo_ids = result.alternate_heplo_ids
  @room_name = result.room_name
  @room_name = @opportunity.unique_room_name(@room_name, except: @room_configuration) if @update_room_name && @room_name.present? && @opportunity
  @room_quoting_method_options = result.room_quoting_method_options
  logger.debug "fetch_room_configuration_options, result.room_quoting_method: #{result.room_quoting_method}"
  logger.debug "fetch_room_configuration_options, result.heating_system_product_line_options: #{result.heating_system_product_line_options.inspect}"
  logger.debug "fetch_room_configuration_options, result.heating_system_product_line_id: #{result.heating_system_product_line_id || 'nil'}"
  @room_quoting_method = result.room_quoting_method
end

#fix_catalogvoid

This method returns an undefined value.

Runs the room's catalog-coherence fixups and reports what changed.



244
245
246
247
248
# File 'app/controllers/room_configurations_controller.rb', line 244

def fix_catalog
  @room_configuration = RoomConfiguration.find(params.expect(:id))
  flash[:info] = @room_configuration.fix_catalog.join('<br>')
  redirect_to room_configuration_path(@room_configuration)
end

#get_itemsvoid

This method returns an undefined value.

Returns the given room configurations' goods line items as JSON, keyed
by item id/sku/quantity, plus their primary product lines.



523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'app/controllers/room_configurations_controller.rb', line 523

def get_items
  ids = params[:ids]
  if ids.blank?
    render json: { error: 'not-found' }.to_json, status: :not_found
  else
    lines = LineItem.where({ resource_type: 'RoomConfiguration', resource_id: RoomConfiguration.where(id: ids.split(',').last) }).goods
    product_lines = []
    line_collection = []
    lines.each do |l|
      line_collection << { id: l.item.id, sku: l.item.sku, quantity: l.quantity }
      product_lines << l.item.primary_product_line.id unless l.item.primary_product_line.nil?
    end
    render json: { items: line_collection, product_lines: product_lines.uniq }
  end
end

#indexvoid

This method returns an undefined value.

Lists room configurations for the current context object (quote, order,
or opportunity), or all room configurations when there is none.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/controllers/room_configurations_controller.rb', line 22

def index
  if context_object
    build_rooms_tab_data(context_object)
    case context_object
    when Quote
      @quote = context_object
      @opportunity = @quote.opportunity
      @editing_locked = @quote.complete?
      @return_path = quote_path(@quote, tab: 'rooms')
    when Order
      @order = context_object
      @opportunity = @order.opportunity
      @editing_locked = @order.editing_locked?
      @return_path = order_path(@order, tab: 'rooms')
    when Opportunity
      @opportunity = context_object
      @return_path = opportunity_path(@opportunity, tab: 'rooms')
    end
  else
    @q = RoomConfiguration.ransack(params[:q])
    @q.sorts = 'name_with_config' if @q.sorts.blank?
    @pagy, @room_configurations = pagy(@q.result.includes(:room_layout_images, :controlled_rooms))
    @room_priorities = []
    @room_statuses = []
  end

  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#lookupvoid

This method returns an undefined value.

Returns room-configuration autocomplete/lookup results, as JSON or a
rendered suggestions partial.



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'app/controllers/room_configurations_controller.rb', line 489

def lookup
  raw = params[:q].presence || params[:term]
  q = raw.try(:upcase)&.split&.first
  @results = RoomConfiguration.lookup(q)
  @pagy, @results = pagy(@results, page: 1, limit: 10)
  respond_to do |format|
    format.json do
      render json: @results.map { |e|
        { 'id' => e.id,
          'label' => e.name_with_customer_opp_and_room,
          'value' => e.reference_number,
          'room_link' => room_configuration_path(e),
          'name' => e.name_with_customer_opp_and_room,
          'just_name' => e.name,
          'reference' => e.reference_number,
          'state' => e.state,
          'created' => (e.created_at || e.updated_at)&.to_date&.to_fs(:crm_default),
          'thumbnail' => e.plan_thumbnail[:path],
          'image_link' => e.plan_thumbnail[:id].nil? ? '#' : upload_path(e.plan_thumbnail[:id]),
          'opportunity' => e.opportunity.try(:name),
          'customer' => e.customer.full_name,
          'customer_link' => customer_path(e.customer) }
      }
    end
    format.html do
      render partial: 'lookup_suggestions', locals: { results: @results }
    end
  end
end

#lookup_rowObject

Returns a single server-rendered row for the rooms table



540
541
542
543
544
545
546
547
# File 'app/controllers/room_configurations_controller.rb', line 540

def lookup_row
  e = RoomConfiguration.find_by(id: params[:id])
  if e.nil?
    render html: ''.html_safe, status: :not_found
  else
    render partial: 'support_cases/rooms_table_row', locals: { rc: e, hide_checkbox: false }
  end
end

#more_information_requiredvoid

This method returns an undefined value.

Workflow event: renders the "more information required" view.



185
186
187
# File 'app/controllers/room_configurations_controller.rb', line 185

def more_information_required
  render action: :more_information_required # Has to be specified since this is called as a concern
end

#newObject

GET /customers/1/opportunities/1/room_configurations/new



128
129
130
131
132
133
134
135
136
137
138
# File 'app/controllers/room_configurations_controller.rb', line 128

def new
  @room_configuration = RoomConfiguration.new(RoomConfiguration.default_attributes(@opportunity.customer.store.id).merge({ has_new_floorplan: false, quote_ids: params[:quote_id] }))
  @room_configuration.opportunity = @opportunity
  @room_configuration.currency = @customer.store.currency
  @room_configuration.reception_date = Date.current
  @coverage_state = 'full'
  # @quote_id = params[:original_quote_id] if params[:original_quote_id]
  @room_configuration.heating_system_product_line_id = nil # 070220 Julia wants this to always be Engineer's choice
  set_edit_variables(false, true)
  @room_configuration.name = @room_name
end

#redesignvoid

This method returns an undefined value.

Renders the redesign form: a working, unsaved deep-dup of the room
configuration seeded from its existing room-layout upload.



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'app/controllers/room_configurations_controller.rb', line 346

def redesign
  @original_rc = RoomConfiguration.find(params.expect(:id))
  @room_configuration = @original_rc.deep_dup
  @room_configuration.reuse_upload_id = @original_rc.uploads.room_layouts.first.try(:id)
  @redesign = true
  @reject_plans = false
  @reject_bom = false

  # Collect quote IDs that will receive the new room configuration
  # Note: We do NOT remove the original room from quotes here - that happens
  # in complete_redesign when the new room is successfully created.
  # Previously, removing on GET caused orphaned rooms if user navigated away.
  quote_ids = @original_rc.quotes.open_quotes.map(&:id)
  quote_ids << params[:quote_id].to_i if params[:quote_id].present?
  @room_configuration.quote_ids = quote_ids.uniq

  # Store the originating quote_id so complete_redesign knows which quote
  # should have the original room removed
  @originating_quote_id = params[:quote_id]

  set_edit_variables
end

#regenerate_plansvoid

This method returns an undefined value.

Regenerates all of the room's installation/electrical plans.



93
94
95
96
# File 'app/controllers/room_configurations_controller.rb', line 93

def regenerate_plans
  @room_configuration.generate_all_plans
  redirect_to @room_configuration
end

#reject_solutionObject

WORKFLOW OVERRIDES (these are mapped to events)



178
179
180
# File 'app/controllers/room_configurations_controller.rb', line 178

def reject_solution
  render action: :reject_solution # Has to be specified since this is called as a concern
end

#restorevoid

This method returns an undefined value.

Restores a cancelled room configuration.



337
338
339
340
# File 'app/controllers/room_configurations_controller.rb', line 337

def restore
  @room_configuration.restore if @room_configuration.cancelled?
  redirect_to_return_path_or_default room_configuration_path(@room_configuration)
end

#showObject

GET /customers/1/opportunities/1/room_configurations/1



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/controllers/room_configurations_controller.rb', line 55

def show
  set_show_variables
  respond_to do |format|
    format.html
    format.pdf do
      # set the heating system in case they're previewing and it's not set yet
      @room_configuration.set_quoted_heating_system_product_line if @room_configuration.quoted_heating_system_pl_id.nil?
      send_upload_accelerated @room_configuration.generate_installation_plan_pdf
    end
    format.xml do
      render xml: @room_configuration.floorplan_xml || ''
    end
    format.dxf do
      # retrieve xml from file + handle cases where there is no xml available or errors
      dtpp = Dxf::DesignToolPlanParser.new(xml_data: @room_configuration.floorplan_xml)

      send_data dtpp.dxf_raw, type: :dxf, disposition: 'attachment', filename: "room_#{@room_configuration.id}.dxf"
      # pass xml and initialize into floor plan dxf converter
      # send file back to browser with proper disposition headers
    end
  end
end

#show_room_planvoid

This method returns an undefined value.

Renders the room's design-tool floor plan.



81
82
83
84
85
86
87
88
# File 'app/controllers/room_configurations_controller.rb', line 81

def show_room_plan
  @room_plan = @room_configuration.room_plan if @room_configuration
  if @room_plan.present?
    render layout: 'www/design_tool'
  else
    render inline: 'Room Plan is missing', status: :not_found
  end
end

#tab_alertsObject

Tab actions for turbo-tabs lazy loading



574
575
576
577
578
579
580
581
# File 'app/controllers/room_configurations_controller.rb', line 574

def tab_alerts
  authorize!(:read, @room_configuration)
  @material_alerts = @room_configuration.get_material_alerts
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_mainvoid

This method returns an undefined value.

Renders the main tab fragment.



586
587
588
589
590
591
592
# File 'app/controllers/room_configurations_controller.rb', line 586

def tab_main
  authorize!(:read, @room_configuration)
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_revisionvoid

This method returns an undefined value.

Renders the revision tab fragment.



608
609
610
611
612
613
614
# File 'app/controllers/room_configurations_controller.rb', line 608

def tab_revision
  authorize!(:read, @room_configuration)
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#tab_ticketsvoid

This method returns an undefined value.

Renders the tickets tab fragment.



597
598
599
600
601
602
603
# File 'app/controllers/room_configurations_controller.rb', line 597

def tab_tickets
  authorize!(:read, @room_configuration)
  respond_to do |format|
    format.html { render layout: should_render_layout? }
    format.turbo_stream
  end
end

#un_vignettevoid

This method returns an undefined value.

Removes the room's linked vignette installation plan image.



563
564
565
566
567
568
569
570
571
# File 'app/controllers/room_configurations_controller.rb', line 563

def un_vignette
  nil
  if @room_configuration.unlink_vignette_installation_plan_image && @room_configuration.update(vignette: false)
    flash[:info] = 'Room was removed from installation plan vignettes'
  else
    flash[:error] = "Can't remove room from installation plan vignettes: #{@room_configuration.errors_to_s}"
  end
  redirect_to room_configuration_path(@room_configuration)
end

#updateObject

PUT /customers/1/opportunities/1/room_configurations/1



295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'app/controllers/room_configurations_controller.rb', line 295

def update
  nil
  @room_configuration = assign_param(@room_configuration, params)
  set_room_attributes_for_next_step

  if @room_configuration.save
    @room_configuration.generate_all_plans if (params[:regenerate_plans] == '1') && @room_configuration.has_plans?
    handle_next_step
  else
    set_edit_variables(true)
    render action: :edit, status: :unprocessable_content
  end
end

#update_installation_plansvoid

This method returns an undefined value.

Saves the installation plan attributes and queues plan regeneration if
the room now has plans.



283
284
285
286
287
288
289
290
291
292
# File 'app/controllers/room_configurations_controller.rb', line 283

def update_installation_plans
  authorize!(:update_installation_plans, @room_configuration)
  if @room_configuration.update(params[:room_configuration].merge(updating_installation_plans: true))
    # try to generate all plans if plans uploaded
    GenerateRoomPlansWorker.perform_in(1.second, @room_configuration.id) if @room_configuration.has_plans?
    redirect_to room_configuration_path(@room_configuration)
  else
    render action: :edit_installation_plans, status: :unprocessable_content
  end
end

#update_namevoid

This method returns an undefined value.

Saves the room's name from the edit_name form.



168
169
170
171
172
173
174
175
# File 'app/controllers/room_configurations_controller.rb', line 168

def update_name
  load_room
  if @room_configuration.update(edit_name_params)
    redirect_to @room_configuration, notice: 'Name updated'
  else
    render :edit_name, status: :unprocessable_content
  end
end

#update_room_configuration_optionsObject

Legacy IQ actions (request_iq_plan, save_iq, revert_iq) removed - IQ system deprecated



426
427
428
429
430
431
# File 'app/controllers/room_configurations_controller.rb', line 426

def update_room_configuration_options
  fetch_room_configuration_options
  respond_to do |format|
    format.turbo_stream
  end
end

#update_room_quoting_methodvoid

This method returns an undefined value.

Refreshes room option fragments after the room quoting method changes.



418
419
420
421
422
423
# File 'app/controllers/room_configurations_controller.rb', line 418

def update_room_quoting_method
  fetch_room_configuration_options
  respond_to do |format|
    format.turbo_stream
  end
end

#vignetteObject

Legacy calculate_instant_quotes action removed - IQ system deprecated



550
551
552
553
554
555
556
557
558
# File 'app/controllers/room_configurations_controller.rb', line 550

def vignette
  nil
  if @room_configuration.create_and_link_vignette_installation_plan_image
    flash[:info] = 'Room was added to installation plan vignettes'
  else
    flash[:error] = "Can't add room to installation plan vignettes: #{@room_configuration.errors_to_s}"
  end
  redirect_to room_configuration_path(@room_configuration)
end