Module: Models::MultiRoom

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

Overview

ActiveSupport::Concern mixin: multi room.

Has and belongs to many collapse

Instance Method Summary collapse

Instance Method Details

#add_line_items_to_all_rooms(sku, qty) ⇒ Object



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

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



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

def add_lines_for_room_configuration(room_configuration)
  return false if room_configurations.find { |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)


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

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

#all_rooms_complete_or_cancelled?Boolean

Returns:

  • (Boolean)


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

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)


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

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)


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

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

#all_rooms_ppd?Boolean

Returns:

  • (Boolean)


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

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

#any_room_ppd?Boolean

Returns:

  • (Boolean)


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

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

#any_rooms_in_design?Boolean

Returns:

  • (Boolean)


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

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

#get_operating_costsObject



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

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


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

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



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

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



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

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



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

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



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

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.



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

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



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

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:



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

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



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

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



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

def suggested_services
  []
end

#synchronization_targetsObject

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



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

def synchronization_targets
  room_configurations
end