Module: Models::MultiRoom

Extended by:
ActiveSupport::Concern
Included in:
Order, Quote
Defined in:
app/concerns/models/multi_room.rb

Has and belongs to many collapse

Instance Method Summary collapse

Instance Method Details

#add_line_items_to_all_rooms(sku, qty) ⇒ Object



175
176
177
# File 'app/concerns/models/multi_room.rb', line 175

def add_line_items_to_all_rooms(sku, qty)
  MultiRoomModel::RoomsLineItemChanger.new(self).add_line_items_to_all_rooms(sku, qty)
end

#add_lines_for_room_configuration(room_configuration) ⇒ Object

this callback is called whenever a room configuration is added, see :before_add in quote, order



84
85
86
87
88
89
90
91
# File 'app/concerns/models/multi_room.rb', line 84

def add_lines_for_room_configuration(room_configuration)
  return false if room_configurations.detect { |rc| rc == room_configuration }

  logger.info "!!! add line call back called for #{room_configuration.id}"
  room_configuration.synchronize_lines(self)
  set_priority(false) if respond_to?(:set_priority)
  true
end

#all_rooms_complete?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'app/concerns/models/multi_room.rb', line 101

def all_rooms_complete?
  room_configurations.all? { |rc| rc.complete? || rc.cancelled? }
end

#all_rooms_complete_or_cancelled?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'app/concerns/models/multi_room.rb', line 113

def all_rooms_complete_or_cancelled?
  room_configurations.all? { |rc| rc.complete? || rc.cancelled? }
end

#all_rooms_complete_or_cancelled_or_draft?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'app/concerns/models/multi_room.rb', line 117

def all_rooms_complete_or_cancelled_or_draft?
  room_configurations.all? { |rc| rc.complete? || rc.cancelled? || rc.draft? }
end

#all_rooms_in_design?Boolean

Returns:

  • (Boolean)


93
94
95
# File 'app/concerns/models/multi_room.rb', line 93

def all_rooms_in_design?
  room_configurations.all?(&:in_design_or_later?)
end

#all_rooms_ppd?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'app/concerns/models/multi_room.rb', line 109

def all_rooms_ppd?
  room_configurations.all?(&:draft?)
end

#any_room_ppd?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'app/concerns/models/multi_room.rb', line 105

def any_room_ppd?
  room_configurations.any?(&:draft?)
end

#any_rooms_in_design?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'app/concerns/models/multi_room.rb', line 97

def any_rooms_in_design?
  room_configurations.any?(&:in_design_or_later?)
end

#get_operating_costsObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'app/concerns/models/multi_room.rb', line 126

def get_operating_costs
  return { status: 'error', message: 'there are no rooms to calculate operating costs' } unless room_configurations.any?

  res = { status: 'ok' }
  rc_ocs = room_configurations.map { |rc| rc.get_operating_costs.merge({ room_configuration_id: rc.id, room_name: rc.name_with_room }) }
  res[:operating_costs_by_room] = rc_ocs
  if rc_ocs.all? { |oc| oc[:status] == 'ok' }
    res[:operating_cost_annual] = rc_ocs.sum { |oc| oc[:operating_cost_annual] }
    res[:operating_cost_by_month_average] = rc_ocs.sum { |oc| oc[:operating_cost_by_month_average] }
    res[:operating_cost_by_coldest_month] = rc_ocs.sum { |oc| oc[:operating_cost_by_coldest_month] }
    res[:message] = 'assuming default thermostat settings, based on average monthly temperatures and electricity rates in your area.'
  else
    res[:status] = 'error'
    res[:message] = rc_ocs.reject { |oc| oc[:status] == 'ok' }.map { |oc| "Room: #{oc[:room_name]}: #{oc[:message]}" }.join(', ')
  end
  res
end


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
# File 'app/concerns/models/multi_room.rb', line 144

def get_recommended_materials(options = {})
  recommended_accessories = []
  if options[:for_room]
    rooms = [options[:for_room]]
  else
    room_ids = line_items.pluck(Arel.sql('distinct room_configuration_id')).compact
    rooms = RoomConfiguration.where(id: room_ids)
  end
  logger.debug "get_recommended_materials(options=#{options.inspect}), rooms.map{|r| r.id}: #{rooms.map(&:id).inspect}"
  rooms.each do |rc|
    rc.get_recommended_materials(options).each do |rc_acc|
      logger.debug "get_recommended_materials, rc: #{rc.id}, rc_acc: #{rc_acc.inspect}"
      found = false
      recommended_accessories.each_with_index do |a, i|
        next unless a['sku'] == rc_acc['sku']

        logger.debug "get_recommended_materials, found: was: #{recommended_accessories[i]['qty']}"
        recommended_accessories[i]['qty'] += rc_acc['qty']
        found = true
        logger.debug "get_recommended_materials, found: now: #{recommended_accessories[i]['qty']}"
      end
      unless found
        logger.debug "get_recommended_materials, not found: adding: #{rc_acc.inspect}"
        recommended_accessories << rc_acc
      end
    end
  end
  logger.debug "get_recommended_materials: recommended_accessories: #{recommended_accessories.inspect}"
  recommended_accessories
end

#heated_sq_ftObject



22
23
24
25
26
27
28
# File 'app/concerns/models/multi_room.rb', line 22

def heated_sq_ft
  sqft = 0
  room_configurations.each do |rc|
    sqft += rc.installation_sqft.to_i if rc.square_footage.to_i > 0
  end
  sqft
end

#insulation_sq_ftObject



30
31
32
33
34
35
36
# File 'app/concerns/models/multi_room.rb', line 30

def insulation_sq_ft
  sqft = 0
  room_configurations.each do |rc|
    sqft += rc.insulation_surface.to_i if rc.room_type&.is_indoor? && (rc.insulation_surface.to_i > 0)
  end
  sqft
end

#prioritize_room(room_configuration) ⇒ Object



15
16
17
18
19
20
# File 'app/concerns/models/multi_room.rb', line 15

def prioritize_room(room_configuration)
  return unless is_a? Order
  return if room_configuration.draft? || room_configuration.complete?

  room_configuration.update_attribute(:priority, 'same day order')
end

#remove_line_items_from_all_rooms(sku) ⇒ Object



179
180
181
# File 'app/concerns/models/multi_room.rb', line 179

def remove_line_items_from_all_rooms(sku)
  MultiRoomModel::RoomsLineItemChanger.new(self).remove_line_items_from_all_rooms(sku)
end

#remove_lines_for_room_configuration(room_configuration) ⇒ Object

This callback is called whenever a room configuration is removed, see :before_remove in quote, order
It removes associated line items if editing is allowed, or blocks removal if line items can't be removed.



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
# File 'app/concerns/models/multi_room.rb', line 53

def remove_lines_for_room_configuration(room_configuration)
  logger.info "MultiRoom#remove_lines_for_room_configuration called for room #{room_configuration.id} on #{self.class.name} #{id}"

  # Find line items associated with this room (query DB to avoid stale cache)
  room_line_items = line_items.where(room_configuration_id: room_configuration.id)

  if room_line_items.exists?
    # Check if editing is locked on this resource
    if respond_to?(:editing_locked?) && editing_locked?
      logger.error "Cannot remove room #{room_configuration.id} from #{self.class.name} #{id}: editing is locked and room has #{room_line_items.count} line items"
      raise ActiveRecord::RecordNotDestroyed, "Cannot remove room '#{room_configuration.name}' because this #{self.class.name.underscore.humanize.downcase} is locked for editing and has line items associated with that room"
    end

    # Remove associated line items
    logger.info "Removing #{room_line_items.count} line items for room #{room_configuration.id}"
    room_line_items.destroy_all

    # Verify all line items were removed
    remaining = line_items.reload.where(room_configuration_id: room_configuration.id)
    if remaining.exists?
      logger.error "Failed to remove all line items for room #{room_configuration.id}: #{remaining.count} remain"
      raise ActiveRecord::RecordNotDestroyed, "Cannot remove room '#{room_configuration.name}': #{remaining.count} line items could not be removed"
    end
  end

  set_priority(false) if respond_to?(:set_priority)
  self.recalculate_shipping = true
  true
end

#replace_line_items_in_all_rooms(orig_sku, new_sku) ⇒ Object



183
184
185
# File 'app/concerns/models/multi_room.rb', line 183

def replace_line_items_in_all_rooms(orig_sku, new_sku)
  MultiRoomModel::RoomsLineItemChanger.new(self).replace_line_items_in_all_rooms(orig_sku, new_sku)
end

#room_configurationsActiveRecord::Relation<RoomConfiguration>

Returns:

  • (ActiveRecord::Relation<RoomConfiguration>)

See Also:



9
10
11
12
# File 'app/concerns/models/multi_room.rb', line 9

has_and_belongs_to_many :room_configurations,
before_remove: :remove_lines_for_room_configuration,
before_add: :add_lines_for_room_configuration,
after_add: :prioritize_room

#suggested_itemsObject



38
39
40
41
42
43
44
45
# File 'app/concerns/models/multi_room.rb', line 38

def suggested_items
  # If we have tempzone, gather all sq.ft
  suggested_items_list = {}
  # room_configurations.sort_by(&:name).each{|rc| rc.append_suggested_items(suggested_items_list, self) }
  # self.append_suggested_towel_warmers(suggested_items_list)
  append_suggested_items(suggested_items_list, self)
  suggested_items_list
end

#suggested_servicesObject



47
48
49
# File 'app/concerns/models/multi_room.rb', line 47

def suggested_services
  []
end

#synchronization_targetsObject

A quote or order always sync to all its rooms since non item locked might have changed



122
123
124
# File 'app/concerns/models/multi_room.rb', line 122

def synchronization_targets
  room_configurations
end