Class: Item::Materials::Checks::RoofDeicing
- Inherits:
-
BaseService
- Object
- BaseService
- Item::Materials::Checks::RoofDeicing
- Defined in:
- app/services/item/materials/checks/roof_deicing.rb
Overview
For Self Regulating Cable only
Defined Under Namespace
Classes: Result
Constant Summary collapse
- MAX_FT_PER_30_AMP_CIRCUIT_120V_R_G_DEICING_CABLE =
Maximum ft per 30 amp circuit 120v r g deicing cable.
214.0
Instance Method Summary collapse
- #container_or_rooms_have_floor_type_but_no_line_items_with_sku_fragment?(container, floor_type_test, sku_fragment) ⇒ Boolean
- #get_rg_heating_elements(container) ⇒ Object
-
#process(container:, options: {}) ⇒ Result
Status and any material alerts.
- #qualify?(container) ⇒ Boolean
Instance Method Details
#container_or_rooms_have_floor_type_but_no_line_items_with_sku_fragment?(container, floor_type_test, sku_fragment) ⇒ Boolean
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/services/item/materials/checks/roof_deicing.rb', line 20 def container_or_rooms_have_floor_type_but_no_line_items_with_sku_fragment?(container, floor_type_test, sku_fragment) res = false rooms = [] if container.is_a?(RoomConfiguration) rooms << container else container.try(:room_configurations).each do |rc| rooms << rc end end rooms.each do |rc| if rc.floor_type.try(floor_type_test) && container.line_items.where(room_configuration_id: rc.id).to_a.none? { |li| li.item.sku.index(sku_fragment) } res = true break end end res end |
#get_rg_heating_elements(container) ⇒ Object
16 17 18 |
# File 'app/services/item/materials/checks/roof_deicing.rb', line 16 def get_rg_heating_elements(container) container.line_items.heating_elements.by_product_line_url(ProductLineUrls::ROOF_GUTTER_DEICING_SELF_REGULATING) end |
#process(container:, options: {}) ⇒ Result
Returns status and any material alerts.
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 |
# File 'app/services/item/materials/checks/roof_deicing.rb', line 44 def process(container:, options: {}) return Result.new(status: :skipped) unless qualify?(container) material_alerts = [] rg_heating_elements = get_rg_heating_elements(container) # get actual sm controls in the line items all_bundled_rg_skus = DEICING_CONTROL_BUNDLES_BY_GROUP.map { |_k, v| v }.flatten all_controls_rg_skus = DEICING_CONTROL_BUNDLES_BY_GROUP.map { |_k, v| v.first } controls = container.line_items.select { |li| all_controls_rg_skus.include?(li.sku) } # get actual relay panels relay_panels = container.line_items.relay_panels # next test if we have more sm controls than we have sm heating elements if (num_controls = controls.sum(&:quantity)) > (num_heating_elements = rg_heating_elements.sum(&:quantity)) = {}.merge() [:room] = container [:recommended_qty] = num_heating_elements [:actual_qty] = num_controls [:items] = controls.filter_map(&:item) [:name] = "At least one heating element per control is recommended." material_alerts << Item::Materials::Alert.new() end # next test for each rg control we have DEICING_CONTROL_BUNDLES_BY_GROUP.select { |_k, v| controls.any? { |li| v.include?(li.sku) } }.each do |group_sku, bundled_rg_skus| # if we have sm control group items in both the bundled group and outside the bundled group, it is not recommended rg_control = Item.find_by(sku: DEICING_CONTROL_BUNDLES_BY_GROUP[group_sku].first) if (non_group_bundle_lis = container.line_items.select { |li| (all_bundled_rg_skus - bundled_rg_skus).include?(li.sku) }).any? # we do, so set up the alert = {}.merge() [:room] = container [:recommended_qty] = 0 [:actual_qty] = 1 items = non_group_bundle_lis.filter_map(&:item) [:name] = "Using the following items is not recommended with the #{DEICING_CONTROL_BUNDLE_SKU_NAME_HASH[group_sku]} roof and gutter deicing control:" [:items] = items [:unmaskable] = true material_alerts << Item::Materials::Alert.new() end # if we have sm controls but not the other group items, it is not recommended bundled_skus_not_in_lis = bundled_rg_skus.select { |sku| container.line_items.find { |li| li.sku == sku }.nil? } next unless bundled_skus_not_in_lis.any? items = bundled_skus_not_in_lis.map { |sku| Item.find_by(sku: sku) } # we are missing some skus, so set up the alert next unless items.any? && items.all? { |item| container.catalog.catalog_items.by_skus(item.sku).first.present? } = {}.merge() [:room] = container [:recommended_qty] = controls.select { |li| li.sku == rg_control.sku }.sum(&:quantity) [:actual_qty] = 0 [:name] = "The following items are recommended with the #{DEICING_CONTROL_BUNDLE_SKU_NAME_HASH[group_sku]} roof and gutter deicing control:" [:items] = items [:unmaskable] = true material_alerts << Item::Materials::Alert.new() end # check relay panels and RCO if we have controls if controls.any? # get minimum number of poles in the rg heating system # roof/gutter deicing heating elements are sold in line items of quantities of 1 foot, so for e.g. 1000 of ET-SR-120, but we do not know at this point how this cable will be cut and into how many sub-zones, thus we don't know the number of heating elements. We can, however, guess the minimum number of heating elements by the maximum number of feet for a given 30 amp circuit (ie per voltage). # we start by counting the number of feet of rg cable of each voltage volts_arr = container.line_items.heating_elements.map { |li| li.item.voltage }.uniq qtys_arr = volts_arr.map { |v| container.line_items.heating_elements.with_product_specification(:voltage, v).to_a.select { |li| li.item.product_lines.any?(&:roof_deicing?) }.sum(&:quantity) } # now count the poles, for 240V we double the max number of feet per circuit (this will halve the number of circuits), but then it will double the number of poles so voltage cancels out in the pole calculation, as long as you separate out the voltages beforehand since they can't be part of the same circuit. Find the minimum number of poles by rounding up ie ceiling. poles = 0 qtys_arr.each_with_index do |q, _i| poles += (q / MAX_FT_PER_30_AMP_CIRCUIT_120V_R_G_DEICING_CABLE).ceil end # get relay_panels required from poles # first test if we have enough actual_poles = relay_panels.to_a.sum { |li| li.num_poles.to_i * li.quantity } if actual_poles < poles relay_panels_sku_qty = HeatingElementProductLineOption.get_relay_panels_from_poles(poles) relay_panels_sku_qty.each do |sku, qty| actual_qty = relay_panels.select { |li| li.sku == sku }.sum(&:quantity) next unless (qty != actual_qty) && container.catalog.catalog_items.by_skus(sku).first.present? && (item = Item.find_by(sku: sku)).present? = {}.merge() [:room] = container [:recommended_qty] = qty [:actual_qty] = actual_qty [:items] = [item] [:unmaskable] = true material_alerts << Item::Materials::Alert.new() end end rcos = container.line_items.select { |li| li.sku == "RCO" } if rcos.any? && controls.find { |li| ["SCA-DUAL"].include?(li.sku) }.nil? && (item = Item.find_by(sku: "RCO")).present? = {}.merge() [:room] = container [:recommended_qty] = 0 [:actual_qty] = rcos.sum(&:quantity) [:items] = [item] [:unmaskable] = true [:name] = "The RCO is only compatible with the Advanced roof and gutter deicing control." material_alerts << Item::Materials::Alert.new() end end if container_or_rooms_have_floor_type_but_no_line_items_with_sku_fragment?(container, :is_slate_shingle?, "ET-CL-CU-SLS") && (items = Item.available_to_public.where("items.sku ilike '%ET-CL-CU-SLS%'")).any? = {}.merge() [:room] = container [:recommended_qty] = 1 [:actual_qty] = 0 [:items] = items [:unmaskable] = true [:name] = "We recommend one of these special order copper 3-prong roof clips with Slate shingle roof and roof and gutter deicing." material_alerts << Item::Materials::Alert.new() end if container_or_rooms_have_floor_type_but_no_line_items_with_sku_fragment?(container, :is_copper?, "ET-CL-CU-P25") && (items = Item.available_to_public.where("items.sku ilike '%ET-CL-CU-P25%'")).any? = {}.merge() [:room] = container [:recommended_qty] = 1 [:actual_qty] = 0 [:items] = items [:unmaskable] = true [:name] = "We recommend one of these special order copper 3-prong roof clips with Copper roof and roof and gutter deicing." material_alerts << Item::Materials::Alert.new() end if container.line_items.none? { |li| li.item.sku.index("SR-PWR-KIT") } && container.line_items.none? { |li| li.item.sku.index("SR-PLUG-KIT") } = {}.merge() [:room] = container [:recommended_qty] = 1 [:actual_qty] = 0 [:items] = [Item.find_by(sku: "SR-PWR-KIT"), Item.find_by(sku: "SR-PLUG-KIT")] [:unmaskable] = true [:name] = "We recommend one of these Power Connection Kits with roof and gutter deicing cable." material_alerts << Item::Materials::Alert.new() end Result.new(status: :ok, alerts: material_alerts) end |
#qualify?(container) ⇒ Boolean
12 13 14 |
# File 'app/services/item/materials/checks/roof_deicing.rb', line 12 def qualify?(container) get_rg_heating_elements(container).any? end |