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: {}) ⇒ Object



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

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