Class: GetRoomOptions

Inherits:
BaseService show all
Defined in:
app/services/get_room_options.rb

Overview

Operation to get room select options and selected option for sub_floor_type, floor_type and heating_system_product_line, as well as returning room_type, environment, allowable voltage options, cable_spacing and coverage_state from inputs

Defined Under Namespace

Classes: Result

Constant Summary collapse

COLDEST_MONTH_AVE_TEMP_THRESHOLD =
40.0

Instance Method Summary collapse

Methods inherited from BaseService

#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger

Constructor Details

This class inherits a constructor from BaseService

Instance Method Details

#default_room_quoting_method(room, instant_quotable_environment) ⇒ Object



273
274
275
276
277
278
# File 'app/services/get_room_options.rb', line 273

def default_room_quoting_method(room, instant_quotable_environment)
  # Legacy IQ path removed - always use engineering
  room_quoting_method = 'engineering'
  logger.debug "default_room_quoting_method, room_quoting_method: #{room_quoting_method}"
  room_quoting_method
end

#ideal_cable_spacing_for(require_cable_spacing, installation_postal_code, sub_floor_type, floor_type) ⇒ Object



280
281
282
283
284
285
286
287
# File 'app/services/get_room_options.rb', line 280

def ideal_cable_spacing_for(require_cable_spacing, installation_postal_code, sub_floor_type, floor_type)
  # convention is we return nil to fallback to the usual default method to determin ideal cable spacing
  cs = nil
  if require_cable_spacing && installation_postal_code && sub_floor_type
    cs = HeatingElementProductLineOption.default_cable_spacings(installation_postal_code, sub_floor_type, floor_type).last
  end
  cs
end

#process(store_id, room = nil, options = {}) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
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
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
147
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
177
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'app/services/get_room_options.rb', line 9

def process(store_id, room = nil, options = {})
  logger.debug "GetRoomOptions.process, options: #{options.inspect}"
  logger.debug "options[:room_quoting_method]: #{options[:room_quoting_method]}"
  selected_room_type_id = selected_sub_floor_type_id = selected_floor_type_id = selected_heating_system_product_line_id = selected_cable_spacing = voltage_id = coverage_state = show_non_public_heplos = nil
  if room
    selected_room_type_id = room.room_type_id
    selected_sub_floor_type_id = room.sub_floor_type_id
    selected_floor_type_id = room.floor_type_id
    selected_heating_system_product_line_id = room.heating_system_product_line_id
    selected_cable_spacing = room.cable_spacing
    voltage_id = room.voltage_id
    coverage_state = room.coverage_state
    alternate_heplo_ids = room.alternate_heplo_ids
    show_non_public_heplos = room.show_non_public_heplos
    installation_postal_code = room.installation_postal_code
  end
  if options[:room_params]
    selected_room_type_id = options[:room_params][:room_type_id].to_i if options[:room_params][:room_type_id].present?
    selected_sub_floor_type_id = options[:room_params][:sub_floor_type_id].to_i if options[:room_params][:sub_floor_type_id].present?
    selected_floor_type_id = options[:room_params][:floor_type_id].to_i if options[:room_params][:floor_type_id].present?
    # if options[:room_params][:heating_system_product_line_id]
    selected_heating_system_product_line_id = options[:room_params][:heating_system_product_line_id].presence.nil? ? nil : options[:room_params][:heating_system_product_line_id].to_i
    # end
    selected_cable_spacing = options[:room_params][:cable_spacing].to_f if options[:room_params][:cable_spacing].to_f > 0
    logger.debug("options[:room_params][:cable_spacing].to_f: #{options[:room_params][:cable_spacing].to_f}")
    logger.debug("selected_cable_spacing: #{selected_cable_spacing}")
    alternate_heplo_ids = options[:room_params][:alternate_heplo_ids] || []
    voltage_id = options[:room_params][:voltage_id].to_i if options[:room_params][:voltage_id].to_i > 0
    coverage_state = options[:room_params][:coverage_state].to_i if options[:room_params][:coverage_state].to_i > 0
    if HeatingElementProductLineOption.valid_membrane_types.include?(options[:room_params][:membrane_type])
      membrane_type = options[:room_params][:membrane_type]
    end
    show_non_public_heplos = true if options[:room_params][:show_non_public_heplos].to_i > 0
    installation_postal_code = options[:room_params][:installation_postal_code] || options[:installation_postal_code]
  end

  room_type = RoomType.find(selected_room_type_id)
  room_type_id = room_type.id
  room_type_key = room_type.seo_key
  environment = options[:environment] || room_type.environment

  room_quoting_method_options = []
  instant_quotable_environment = false
  instant_quotable_environment = true if HeatingElementProductLineOption.instant_quotable_environments.include?(environment)
  room_quoting_method_options = [%w[Engineering engineering]]
  # Legacy IQ option removed - IQ system deprecated
  selected_room_quoting_method = options[:room_quoting_method] || default_room_quoting_method(room, instant_quotable_environment)
  use_public_heplos = true
  use_public_heplos = nil if show_non_public_heplos # important because false here instead of nil will behave VERY differently!
  use_public_heplos = nil if options[:room_quoting_method] == 'engineering' # this is an override regardless of room setting
  use_public_heplos = true if options[:public] == true # this is an override regardless of room setting

  room_quoting_method = if room_quoting_method_options.any? { |rqmo| rqmo.last == selected_room_quoting_method }
                          selected_room_quoting_method
                        else
                          room_quoting_method_options.first.last
                        end

  sub_floor_type_options = HeatingElementProductLineOption.options_for_select(assoc_sym = :sub_floor_type, assoc_sort_field = 'name',
                                                                              assoc_name_method = 'name', { is_public: use_public_heplos, environment:, store_id: })
  sub_floor_type_options_by_key = HeatingElementProductLineOption.options_for_select(assoc_sym = :sub_floor_type, assoc_sort_field = 'name',
                                                                                     assoc_name_method = 'name', { is_public: use_public_heplos, environment:, store_id: }, include_blank = false, assoc_key = 'seo_key')
  sub_floor_type_id = nil

  if sub_floor_type_options.any?
    if sub_floor_type_options.any? { |t_a| t_a[1] == selected_sub_floor_type_id }
      sub_floor_type_id = selected_sub_floor_type_id
    else
      sub_floor_type_options = [['Please Select...', nil]] + sub_floor_type_options if options[:add_prompt_to_sub_floor_and_floor_type_options]
      sub_floor_type_id = HeatingElementProductLineOption.get_default_subfloor_type_id
    end
  end
  sub_floor_type = sub_floor_type_id.nil? ? nil : SubFloorType.find(sub_floor_type_id)
  sub_floor_type_key = sub_floor_type.nil? ? nil : sub_floor_type.seo_key

  logger.debug "floor_type_options for heplos: #{{ is_public: use_public_heplos, environment:,
                                                   sub_floor_type_id:, store_id: }.inspect}"
  use_room_type_id = nil
  use_room_type_id = room_type_id if environment.downcase.index('outdoor')
  floor_type_options = HeatingElementProductLineOption.options_for_select(assoc_sym = :floor_type, assoc_sort_field = 'name', assoc_name_method = 'name',
                                                                          { is_public: use_public_heplos, environment:, sub_floor_type_id:, store_id:, room_type_id: use_room_type_id })
  floor_type_options_by_key = HeatingElementProductLineOption.options_for_select(assoc_sym = :floor_type, assoc_sort_field = 'name',
                                                                                 assoc_name_method = 'name', { is_public: use_public_heplos, environment:, sub_floor_type_id:, store_id:, room_type_id: use_room_type_id }, include_blank = false, assoc_key = 'seo_key')
  if floor_type_options.any? { |t_a| t_a[1] == selected_floor_type_id }
    floor_type_id = selected_floor_type_id
  else
    floor_type_options = [['Please Select...', nil]] + floor_type_options if options[:add_prompt_to_sub_floor_and_floor_type_options]
    # here we fallback to default for the environment unless it's not present in the valid options at which point we default to the first valid option
    floor_type_id = HeatingElementProductLineOption.get_default_floor_type_id_for_environment(environment)
    floor_type_id = floor_type_options&.first&.[](1) if floor_type_options.any? and floor_type_options.none? { |t_a| t_a[1] == floor_type_id }
  end
  floor_type = FloorType.find(floor_type_id)
  floor_type_key = floor_type.seo_key

  # check coverage options and state
  coverage_options = [['Full', 0]]
  # only room types that support tire tracks get this as an option
  coverage_options << ['Tire Tracks Only', 4] if room_type.tire_tracks_option? and floor_type_key != 'paver'
  # select default if no coverage options match requested coverage state
  coverage_state ||= coverage_options.first.last unless coverage_options.any? { |cs_ar| cs_ar.last == coverage_state }

  if options[:include_blank_heating_system] == true && floor_type.name.downcase.index('existing').nil?
    blank_option_name = "Engineer's choice"
    starting_heating_system_product_line_option = [[blank_option_name, nil]]
  else
    starting_heating_system_product_line_option = []
  end
  # Legacy IQ condition removed - now only engineering path
  if false # Legacy IQ path - never executes
    heating_system_product_line_options = starting_heating_system_product_line_option
    heating_system_product_line_options_by_url = starting_heating_system_product_line_option
    heating_system_product_line_id = nil
    use_instant_quotable_heplos = true # Here we only offer instant quotable options
  else
    use_instant_quotable_heplos = nil # important because false here instead of nil will behave VERY differently!
    base_heating_system_product_line_options = HeatingElementProductLineOption.options_for_select(assoc_sym = :product_line, assoc_sort_field = nil,
                                                                                                  assoc_name_method = 'heating_system_type_name', { is_public: use_public_heplos, environment:, sub_floor_type_id:, floor_type_id:, store_id:, room_type_id: use_room_type_id }, include_blank = false)
    base_heating_system_product_line_options_by_url = starting_heating_system_product_line_option + HeatingElementProductLineOption.options_for_select(
      assoc_sym = :product_line, assoc_sort_field = nil, assoc_name_method = 'heating_system_type_name', { is_public: use_public_heplos,
                                                                                                           environment:, sub_floor_type_id:, floor_type_id:, store_id:, room_type_id: use_room_type_id }, include_blank = false, assoc_key = 'slug_ltree'
    )
    # if only one option, then just choose the damn thing
    if base_heating_system_product_line_options.size > 1
      heating_system_product_line_options = starting_heating_system_product_line_option + base_heating_system_product_line_options
      heating_system_product_line_options_by_url = starting_heating_system_product_line_option + base_heating_system_product_line_options_by_url
    else
      heating_system_product_line_options = base_heating_system_product_line_options
      heating_system_product_line_options_by_url = base_heating_system_product_line_options_by_url
    end
    selected_heating_system_product_line_id_is_public = false
    if HeatingElementProductLineOption.get_field_array_from_options(:is_public,
                                                                    { environment:, sub_floor_type_id:, floor_type_id:,
                                                                      product_line_id: selected_heating_system_product_line_id, store_id: }).first == true
      selected_heating_system_product_line_id_is_public = true
    end
    if heating_system_product_line_options.any? do |t_a|
         t_a[1] == selected_heating_system_product_line_id
       end and (selected_heating_system_product_line_id.nil? or selected_heating_system_product_line_id_is_public or options[:floor_type_id_changed] != '1')
      # keep room's heating_system_product_line if possible
      heating_system_product_line_id = selected_heating_system_product_line_id
    else
      # use default since the floor type has changed or the previous heating system is not a publicly available one
      heplo = HeatingElementProductLineOption.options_scope({ is_public: use_public_heplos, environment:,
                                                              sub_floor_type_id:, floor_type_id:, store_id: }).first
      heating_system_product_line_id = nil
      # 080819 ramie: Anatoliy asks for nil as an option for crm
      heating_system_product_line_id = heplo.product_line_id if heplo.present? && use_public_heplos
    end
  end
  heating_system_product_line = heating_system_product_line_id.nil? ? nil : ProductLine.find(heating_system_product_line_id)
  heating_system_product_line_url = heating_system_product_line.nil? ? nil : heating_system_product_line.slug_ltree.to_s

  require_cable_spacing = HeatingElementProductLineOption.get_field_array_from_options(:require_cable_spacing,
                                                                                       { is_public: use_public_heplos, environment:, sub_floor_type_id:, floor_type_id:,
                                                                                         product_line_id: heating_system_product_line_id, store_id: }).first
  ideal_cable_spacing = ideal_cable_spacing_for(require_cable_spacing, installation_postal_code, sub_floor_type,
                                                floor_type) || HeatingElementProductLineOption.get_field_array_from_options(:ideal_cable_spacing,
                                                                                                                            { is_public: use_public_heplos, environment:, sub_floor_type_id:, floor_type_id:,
                                                                                                                              product_line_id: heating_system_product_line_id, store_id: }).first
  cable_spacing = if selected_heating_system_product_line_id == heating_system_product_line_id
                    # keep room's if possible since the product line hasn't changed
                    selected_cable_spacing
                  else
                    # use ideal since the product line has changed
                    ideal_cable_spacing
                  end

  # 072419 ramie: Scott asks for nil as an option for crm # 041519 ramie: let's try not nil even for crm if use_public_heplos # don't let cable_spacing be nil if this is public
  cable_spacing ||= ideal_cable_spacing if use_public_heplos
  logger.debug("selected_heating_system_product_line_id: #{selected_heating_system_product_line_id}, heating_system_product_line_id: #{heating_system_product_line_id}")
  logger.debug("cable_spacing: #{cable_spacing}")
  cable_spacing_options = []
  if heating_system_product_line and heating_system_product_line.heating_system_type_name == 'Slab Heat Cable'
    cable_spacing_options = HeatingElementProductLineOption.shc_cable_spacing_for_select
  elsif heating_system_product_line and heating_system_product_line.heating_system_type_name == 'Snow Melt Cable'
    cable_spacing_options = HeatingElementProductLineOption.smc_cable_spacing_for_select
  elsif heating_system_product_line and heating_system_product_line.heating_system_type_name.to_s.index('TempZone') and heating_system_product_line.heating_system_type_name.to_s.index('Cable')
    cable_spacing_options = HeatingElementProductLineOption.tz_cable_spacing_for_select({ tz_cable_pl_url: heating_system_product_line.slug_ltree.to_s,
                                                                                          is_public: use_public_heplos })
  end
  all_alternate_heplos = HeatingElementProductLineOption.options_scope({ sub_floor_type_id:, floor_type_id: floor_type.id,
                                                                         is_public: use_public_heplos, instant_quotable: use_instant_quotable_heplos, environment:, store_id:, room_type_id: use_room_type_id })
  all_alternate_heplo_options = all_alternate_heplos.sort_by do |heplo|
                                  [heplo.product_line.priority.to_i, heplo.ideal_cable_spacing.to_i]
                                end.map { |heplo| [heplo.name_with_cable_spacing, heplo.id] }

  use_smc_voltages = false
  use_smc_voltages = all_alternate_heplos.any? { |h| h.product_line.slug_ltree.to_s == ProductLineUrls::SNOW_MELTING_CABLE } if environment == 'Outdoor'
  include_24 = true
  include_24 = false if use_public_heplos == true
  voltage_options = [["Engineer's choice",
                      nil]].concat(HeatingElementProductLineOption.voltage_options_for_select(heating_system_product_line, include_24, environment,
                                                                                              use_smc_voltages))
  voltage_id = nil unless voltage_options.any? { |vo| vo == voltage_id }

  membrane_options = []
  offer_prodeso = all_alternate_heplos.any? { |h| h.membrane_type.to_s.downcase.index('prodeso') }
  offer_ditra = all_alternate_heplos.any? { |h| h.membrane_type.to_s.downcase.index('ditra') }
  if offer_prodeso or offer_ditra
    membrane_options = [['Let Us Choose', nil]]
    membrane_options << %w[Prodeso Prodeso] if offer_prodeso
    membrane_options << ['DITRA-HEAT (Sold Separately)', 'Ditra'] if offer_ditra
  end
  membrane_type = nil if membrane_type.to_s.downcase.index('prodeso') and !offer_prodeso
  membrane_type = nil if membrane_type.to_s.downcase.index('ditra') and !offer_ditra

  # Populate cable spacing options from database when:
  # 1. heating_system_product_line is nil (Let Us Choose), OR
  # 2. cable_spacing_options is empty (covers both indoor with membranes and outdoor snow melting)
  if heating_system_product_line.nil? || cable_spacing_options.empty?
    cable_spacing_options = HeatingElementProductLineOption.get_field_array_from_options(:ideal_cable_spacing,
                                                                                         { sub_floor_type_id:, floor_type_id: floor_type.id, is_public: use_public_heplos, instant_quotable: use_instant_quotable_heplos, environment:,
                                                                                           store_id:, room_type_id: use_room_type_id, membrane_type: }).compact.sort.map do |cs|
      ["#{cs} #{environment == 'Indoor' ? HeatingElementProductLineOption::CABLE_SPACING_EXTRA_COPY[cs.to_s] : nil}", cs]
    end
  end

  # cable_spacing_options.insert(0, ["Let Us Choose", nil]) if cable_spacing_options.present?
  cable_spacing_options = cable_spacing_options.uniq.compact.reject { |a| a[0].nil? }
  # Preserve user's selected cable spacing if it's valid for the current options
  if selected_cable_spacing.present? && cable_spacing_options.any? { |cs_a| cs_a[1] == selected_cable_spacing }
    cable_spacing = selected_cable_spacing
  elsif cable_spacing.present? && cable_spacing_options.none? { |cs_a| cs_a[1] == cable_spacing }
    cable_spacing = nil
  end

  room_name = nil
  room_name = "#{room_type.name}" if options[:update_room_name] == true

  Result.new(room_type:,
             room_type_id:,
             room_type_key:,
             room_quoting_method_options:,
             room_quoting_method:,
             environment:,
             sub_floor_type_options:,
             sub_floor_type_options_by_key:,
             sub_floor_type:,
             sub_floor_type_id:,
             sub_floor_type_key:,
             floor_type_options:,
             floor_type_options_by_key:,
             floor_type:,
             floor_type_id:,
             floor_type_key:,
             heating_system_product_line_options:,
             heating_system_product_line_options_by_url:,
             heating_system_product_line:,
             heating_system_product_line_id:,
             heating_system_product_line_url:,
             voltage_options:,
             voltage_id:,
             require_cable_spacing:,
             cable_spacing_options:,
             cable_spacing:,
             all_alternate_heplo_options:,
             alternate_heplo_ids:,
             coverage_state:,
             coverage_options:,
             membrane_type:,
             membrane_options:,
             room_name:)
end