Class: Item::PopulateItemPopularity

Inherits:
BaseService show all
Defined in:
app/services/item/populate_item_popularity.rb

Overview

Service object: populate item popularity.

Instance Attribute Summary

Attributes inherited from BaseService

#options

Instance Method Summary collapse

Methods inherited from BaseService

#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger

Constructor Details

This class inherits a constructor from BaseService

Instance Method Details

#base_item_queryObject



28
29
30
# File 'app/services/item/populate_item_popularity.rb', line 28

def base_item_query
  LineItem.joins(:order).where.not(item_id: nil).where(LineItem[:discounted_price].gteq(0)).merge(Order.so_only.invoiced.where.not(shipped_date: nil)).group(:item_id)
end

#processObject



4
5
6
7
8
9
10
11
# File 'app/services/item/populate_item_popularity.rb', line 4

def process
  res = {}
  res[:items_updated] = process_items
  res[:items_updated_last_date] = process_item_last_sale_date
  res[:items_updated_first_date] = process_item_first_sale_date
  res[:product_lines_updated] = process_product_lines
  res
end

#process_item_first_sale_dateObject



44
45
46
47
48
49
50
51
52
53
54
# File 'app/services/item/populate_item_popularity.rb', line 44

def process_item_first_sale_date
  item_dates = base_item_query.minimum(Order[:shipped_date])

  Item.transaction do
    Item.where.not(first_sale_date: nil).update_all(first_sale_date: nil)
    item_dates.each do |item_id, last_date|
      Item.where(id: item_id).update_all(first_sale_date: last_date)
    end
  end
  item_dates.size
end

#process_item_last_sale_dateObject



32
33
34
35
36
37
38
39
40
41
42
# File 'app/services/item/populate_item_popularity.rb', line 32

def process_item_last_sale_date
  item_dates = base_item_query.maximum(Order[:shipped_date])

  Item.transaction do
    Item.where.not(last_sale_date: nil).update_all(last_sale_date: nil)
    item_dates.each do |item_id, last_date|
      Item.where(id: item_id).update_all(last_sale_date: last_date)
    end
  end
  item_dates.size
end

#process_itemsObject



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/services/item/populate_item_popularity.rb', line 13

def process_items
  item_counters = LineItem.joins(:order).merge(Order.so_only).where(LineItem[:created_at].gteq(5.years.ago)).where.not(item_id: nil).group(:item_id).count
  # item active and not hidden will get a double score boost
  active_item_ids = CatalogItem.joins(store_item: :item).merge(Item.goods).where(state: %w[active]).distinct.pluck(Item[:id])
  # Reset
  Item.update_all(popularity: 0)
  Item.transaction do
    item_counters.each do |item_id, counter|
      counter *= 2 if active_item_ids.include?(item_id)
      Item.where(id: item_id).update_all("popularity = #{counter} + popularity_offset")
    end
  end
  item_counters.size
end

#process_product_lines(product_lines = nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'app/services/item/populate_item_popularity.rb', line 56

def process_product_lines(product_lines = nil)
  product_lines ||= ProductLine.all
  product_lines.update_all(popularity: 0)
  product_lines.each do |pl|
    next if pl.ltree_path_ids.blank?

    base_relation = Item.where(Item[:primary_pl_path_ids].ltree_descendant(pl.ltree_path_ids))
    # Narrow to product categories linked to this product line tree
    pc_ids = ProductLine.where(ProductLine[:ltree_path_ids].ltree_descendant(pl.ltree_path_ids))
                        .joins(:product_categories)
                        .pluck('product_categories.id')
                        .uniq
    if pc_ids.present?
      pc_paths = ProductCategory.where(id: pc_ids).pluck(:ltree_path_ids).compact
      base_relation = base_relation.where("items.pc_path_ids <@ ANY(ARRAY[?]::ltree[])", pc_paths) if pc_paths.present?
    end
    item_popularity = base_relation.sum("COALESCE(items.popularity,0) + COALESCE(items.popularity_offset,0)")
    last_sale_date = base_relation.maximum(:last_sale_date)
    first_sale_date = base_relation.minimum(:first_sale_date)
    popularity = item_popularity + pl.popularity_offset.to_i
    pl.update_columns(popularity:, last_sale_date:, first_sale_date:)
  end
  product_lines.size
end