Class: Item::Materials::Checks::Recommended

Inherits:
BaseService
  • Object
show all
Defined in:
app/services/item/materials/checks/recommended.rb

Overview

Service object: recommended.

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Instance Method Details

#process(container:, options: {}) ⇒ Result

Returns status and any material alerts.

Parameters:

  • container (Quote, Order, RoomConfiguration)

    the resource to check

  • options (Hash) (defaults to: {})

    shared check options passed by Item::Materials::Check

Options Hash (options:):

  • :for_www (Boolean)

    whether the check runs for the public site

  • :for_cart (Boolean)

    whether the check runs for the cart

Returns:

  • (Result)

    status and any material alerts



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
# File 'app/services/item/materials/checks/recommended.rb', line 14

def process(container:, options: {})
  container_rec_materials = container.get_recommended_materials(options)

  return Result.new(status: :skipped) if container_rec_materials.blank?

  material_alerts = []
  rec_materials_hash = container_rec_materials.group_by { |p| p['exclusive_group_type'] }.sort_by do |k, _v|
    ExclusiveItemGroup.find_by(key: k).position
  rescue StandardError
    99
  end.to_h
  rec_materials_hash.each do |group_type, materials|
    sorted_materials = materials.sort_by do |a|
      [a['sku'], begin
        Item.find_by(sku: a['sku']).product_category.priority
      rescue StandardError
        99
      end]
    end
    Rails.logger.debug { "#{container.class.name}:#{container.id}: get_material_alerts, group_type: #{group_type}, materials: #{materials.inspect}" }
    if group_type.present?
      exclusive_item_group = ExclusiveItemGroup.find_by(key: group_type)
      sku_list = sorted_materials.map { |a| a['sku'] }
      recommended_qty = sorted_materials.first['qty']
      actual_qty = container.line_items.select { |l| sku_list.include?(l.sku) }.sum(&:quantity)
      if exclusive_item_group.per_thermostat
        recommended_qty = container.line_items.thermostats.to_a.sum(&:quantity)
      else
        recommended_qty = 1
        actual_qty = container.line_items.select { |l| sku_list.include?(l.sku) }.sum(&:quantity)
      end
      Rails.logger.debug { "#{container.class.name}:#{container.id}: get_material_alerts, container.line_items.map{|li| li.sku}: #{container.line_items.map(&:sku).inspect}" }
      Rails.logger.debug { "#{container.class.name}:#{container.id}: get_material_alerts, sku_list: #{sku_list.inspect}, recommended_qty: #{recommended_qty}, actual_qty: #{actual_qty}" }
      if (actual_qty != recommended_qty) && sorted_materials.any? && sorted_materials.all? do |a|
        container.catalog.catalog_items.by_skus(a['sku']).first.present? && IqAccessoryFilter.for_item_or_exclusive_item_group(exclusive_item_group).for_customer(container.customer).first.blank?
      end
        ma_options = {}.merge(options)
        ma_options[:room] = container
        ma_options[:group_type] = exclusive_item_group.key
        ma_options[:group_name] = exclusive_item_group.name
        ma_options[:recommended_qty] = recommended_qty
        ma_options[:actual_qty] = actual_qty
        ma_options[:items] = sorted_materials.filter_map { |a| Item.find_by(sku: a['sku']) }
        material_alerts << Item::Materials::Alert.new(ma_options)
      end
    else
      sorted_materials.each do |a|
        # here we skip alerts for membrane and instead use these to calculate total membrane coverage recommended vs actual total membrane coverage
        dont_skip_alert = true
        item = Item.find_by(sku: a['sku'])
        dont_skip_alert = false if item.is_membrane?
        recommended_qty = a['qty']
        actual_qty = container.line_items.select { |l| l.sku == a['sku'] }.sum(&:quantity)
        Rails.logger.debug { "#{container.class.name}: #{container.id}: get_material_alerts, container.line_items.map{|li| li.sku}: #{container.line_items.map(&:sku).inspect}" }
        Rails.logger.debug { "#{container.class.name}:#{container.id}: get_material_alerts, a['sku']: #{a['sku']}, recommended_qty: #{recommended_qty}, actual_qty: #{actual_qty}" }
        unless dont_skip_alert && (actual_qty != recommended_qty) && container.catalog.catalog_items.by_skus(a['sku']).first.present? && item.present? && IqAccessoryFilter.for_item_or_exclusive_item_group(item).for_customer(container.customer).first.blank?
          next
        end

        ma_options = {}.merge(options)
        ma_options[:room] = container
        ma_options[:recommended_qty] = recommended_qty
        ma_options[:actual_qty] = actual_qty
        item = Item.find_by(sku: a['sku'])
        ma_options[:items] = [item]
        nil
        underlayment_warning_for_www = nil
        underlayment_alert = if item.is_underlayment?
                               if item.is_thermalsheet?
                                 "ThermalSheet"
                               elsif item.is_cork?
                                 "Cork"
                               elsif item.is_cerazorb?
                                 "CeraZorb®"
                               end
                             end
        ma_options[:unmaskable] = true if item.is_junction_box? # we make these unmaskable, ie part of a system
        if underlayment_alert.present? && (recommended_qty > actual_qty) && options[:for_www]
          underlayment_warning_for_www = "We always recommend insulating a concrete subfloor from the radiant heating system using our #{underlayment_alert} underlayment for optimal performance and efficiency. "
        end
        ma_options[:name] = underlayment_warning_for_www
        material_alerts << Item::Materials::Alert.new(ma_options)
      end
    end
  end

  Result.new(status: :ok, alerts: material_alerts)
end