Class: Bom::XmlFromZone

Inherits:
Object
  • Object
show all
Includes:
Service
Defined in:
app/services/bom/xml_from_zone.rb

Instance Method Summary collapse

Methods included from Service

#attributes_used, #build_result, call, #logger

Methods included from Service::Initializer

#initialize

Instance Method Details

#callObject



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
# File 'app/services/bom/xml_from_zone.rb', line 13

def call
  heating_system_type_name = heating_system_pl.heating_system_type_name
  require_expansion_joint = HeatingElementProductLineOption.get_field_array_from_options(:require_expansion_joint, {:floor_type_id => floor_type.id, :product_line_id => heating_system_pl.id}).first
  ideal_cable_spacing = HeatingElementProductLineOption.get_field_array_from_options(:ideal_cable_spacing, {:floor_type_id => floor_type.id, :product_line_id => heating_system_pl.id}).first

  est_element = REXML::Element.new "estimate"
  est_element.add_attribute("catalog_id", catalog.id.to_s)
  est_element.add_attribute("floor_type_id", floor_type.id.to_s)
  est_element.add_attribute("product_type", floor_type.product) # legacy product TZ, SM, EV2
  est_element.add_attribute("currency_code", catalog.currency)

  criteria_keys = {}
  criteria_keys[:zones] = zones
  criteria_keys[:room_type] = RoomType.find(HeatingElementProductLineOption.get_default_room_type_id_for_environment(floor_type.environment))
  criteria_keys[:floor_type] = floor_type
  criteria_keys[:sub_floor_type] = sub_floor_type || SubFloorType.find_by(seo_key: "wood")
  criteria_keys[:heating_system_type] = heating_system_type_name
  criteria_keys[:coverage_state] = (options[:coverage_state].to_i rescue 0)
  criteria_keys[:voltage] = options[:voltage]
  legacy_style = false

  if ["TempZone Flex Roll", "TempZone Easy Mat", "Environ Flex Roll", "Environ Easy Mat", "Slab Heat Cable", "Slab Heat Mat"].include?(heating_system_type_name)
   legacy_style = true
    if ["Slab Heat Cable"].include?(heating_system_type_name)
      criteria_keys[:cable_spacing] = options[:cable_spacing] ||= ideal_cable_spacing
    end
  elsif ["Snow Melt Mat", "Snow Melt PowerMat", "Snow Melt OmniMat", "Snow Melt EcoMat", "Snow Melt Cable"].include?(heating_system_type_name)
    criteria_keys[:expansion_joint_spacing] = options[:expansion_joint_spacing] if require_expansion_joint
    criteria_keys[:expansion_joint_spacing] ||= 20 if require_expansion_joint
    if ["Snow Melt Cable"].include?(heating_system_type_name)
      criteria_keys[:cable_spacing] = options[:cable_spacing] ||= ideal_cable_spacing
    end
  end
  hsc_bom = HeatingSystemCalculator::BaseCalculator.new(
    criteria_keys.merge(
      catalog: self.catalog,
      heating_system_product_line: heating_system_pl,
      require_expansion_joint: require_expansion_joint
    )
  ).calculate_system

  if hsc_bom and hsc_bom['found_solution']
    est_element.add_attribute("coverage_percentage", hsc_bom['coverage_percentage'].to_i.to_s)
    est_element.add_attribute("area", hsc_bom['target_area'].to_f.round(1).to_s)
    insert_xml_from_bom_soln_into_element(hsc_bom, est_element, legacy_style, options[:pricing_formula])
    return est_element.to_s
  else
    etailer_iq_details = ""
    etailer_iq_details = ", from e-tailer iq domain: #{quick_estimator.domain_name}" if quick_estimator
    err_msg = "BOM::XmlFromZone: #{hsc_bom['error_message']}"
    ErrorReporting.warning(err_msg, attributes_used)
    return ""
  end

end

#get_pricing(msrp_price, pricing_formula) ⇒ Object (protected)



164
165
166
167
168
169
170
# File 'app/services/bom/xml_from_zone.rb', line 164

def get_pricing(msrp_price, pricing_formula)
  pricing = msrp_price
  if pricing_formula
    pricing = eval(pricing_formula.gsub('msrp_price', msrp_price.to_s))
  end
  return pricing
end

#insert_xml_from_bom_soln_into_element(bom, est_element, legacy_style, pricing_formula = nil) ⇒ Object (protected)



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
# File 'app/services/bom/xml_from_zone.rb', line 71

def insert_xml_from_bom_soln_into_element(bom, est_element, legacy_style, pricing_formula=nil)
  logger.debug "bom['foundsolution']: #{bom['foundsolution']}"
  logger.debug "bom['controls']: #{bom['controls'].inspect}"
  unless bom['foundsolution'] == false
    # controls
    if legacy_style
      # for backward compatibility do TZ controls as per before
      bom['controls'].sort_by{|i| [i['price'], i['description']]}.each do |control|
        ct_element = REXML::Element.new control['symbol'].downcase
        ct_element.add_attribute("qty", control['qty'].to_s)
        ct_element.add_attribute("price", get_pricing(control['price'].round(2), pricing_formula).to_s)
        ct_element.add_attribute("description", control['description'])
        ct_element.add_attribute("sku", control['sku'])
        ct_element.add_attribute("third_party_part_number", control['third_party_part_number'])
        ct_element.add_attribute("third_party_sku", control['third_party_sku'])
        ct_element.add_attribute("cat_id", control['cat_id'].to_s)
        item = Item.find_by(sku: control['sku'])
        ct_element.add_attribute("image_url", item.thumbnail_url)
        est_element.add_element ct_element
      end
    else
      # otherwise we do control groups to bundle groups of skus in a single control group option
      bom_control_groups = (bom['controls'] || []).group_by{|p| p["bundle_sku"]}
      # here the non optional relay panels (by bom convention in controls) should be added to the non optional products, their bundle sku will be nil
      bom_required_controls = bom_control_groups[nil] || []
      bom_required_controls.sort_by{|i| [i['price'], i['description']]}.each do |control|
        ct_element = REXML::Element.new control['symbol'].downcase
        ct_element.add_attribute("qty", control['qty'].to_s)
        ct_element.add_attribute("price", get_pricing(control['price'].round(2), pricing_formula).to_s)
        ct_element.add_attribute("description", control['description'])
        ct_element.add_attribute("sku", control['sku'])
        ct_element.add_attribute("third_party_part_number", control['third_party_part_number'])
        ct_element.add_attribute("third_party_sku", control['third_party_sku'])
        ct_element.add_attribute("cat_id", control['cat_id'].to_s)
        item = Item.find_by(sku: control['sku'])
        ct_element.add_attribute("image_url", item.thumbnail_url)
        est_element.add_element ct_element
      end
      # get the radio optional control groups
      bom_optional_groups = []
      bom_control_groups.each do |bundle_sku, products|
        bom_optional_groups << products if bundle_sku
      end
      bom_optional_groups.each do |control_group|
        cg_element = REXML::Element.new 'control_group'
        cg_element.add_attribute("description", control_group.first['description'])
        control_group.each do |control|
          ct_element = REXML::Element.new control['symbol'].downcase
          ct_element.add_attribute("qty", control['qty'].to_s)
          ct_element.add_attribute("price", get_pricing(control['price'].round(2), pricing_formula).to_s)
          ct_element.add_attribute("description", control['description'])
          ct_element.add_attribute("sku", control['sku'])
          ct_element.add_attribute("third_party_part_number", control['third_party_part_number'])
          ct_element.add_attribute("third_party_sku", control['third_party_sku'])
          ct_element.add_attribute("cat_id", control['cat_id'].to_s)
          item = Item.find_by(sku: control['sku'])
          ct_element.add_attribute("image_url", item.thumbnail_url)
          cg_element.add_element ct_element
        end
        est_element.add_element cg_element
      end
    end
    # heating elements
    bom['elements'].sort_by{|i| [i['price'], i['description']]}.each do |element|
      he_element = REXML::Element.new "heating_element"
      he_element.add_attribute("qty", element['qty'].to_s)
      he_element.add_attribute("price", get_pricing(element['price'].round(2), pricing_formula).to_s)
      he_element.add_attribute("description", element['description'])
      he_element.add_attribute("sku", element['sku'])
      he_element.add_attribute("third_party_part_number", element['third_party_part_number'])
      he_element.add_attribute("third_party_sku", element['third_party_sku'])
      he_element.add_attribute("cat_id", element['cat_id'].to_s)
      item = Item.find_by(sku: element['sku'])
      he_element.add_attribute("image_url", item.thumbnail_url)
      est_element.add_element he_element
    end
    # accessories
    (bom['accessories'] || []).select{|i| i['exclusive_group_type'].nil?}.sort_by{|i| [i['price'], i['description']]}.each do |element|
      ac_element = REXML::Element.new "accessory"
      ac_element.add_attribute("qty", element['qty'].to_s)
      ac_element.add_attribute("price", get_pricing(element['price'].round(2), pricing_formula).to_s)
      ac_element.add_attribute("description", element['description'])
      ac_element.add_attribute("sku", element['sku'])
      ac_element.add_attribute("third_party_part_number", element['third_party_part_number'])
      ac_element.add_attribute("third_party_sku", element['third_party_sku'])
      ac_element.add_attribute("cat_id", element['cat_id'].to_s)
      item = Item.find_by(sku: element['sku'])
      ac_element.add_attribute("image_url", item.thumbnail_url)
      est_element.add_element ac_element
    end
  end
end