Class: Item::CycleCountScheduler

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

Instance Method Summary collapse

Methods inherited from BaseService

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

Constructor Details

#initialize(store_id, options = {}) ⇒ CycleCountScheduler

highest priority gets scheduled first
default max quota of 200
lead, cable, wire should only add a max of 50 to the quota
group by product lines so similar items are counted together
always add store items marked always_add_to_monthly_cycle_count



10
11
12
13
14
15
16
17
# File 'app/services/item/cycle_count_scheduler.rb', line 10

def initialize(store_id, options = {})
  @store = Store.find(store_id)
  @due_date = options[:due_date] || Date.current
  @max_items = options[:max_items] || 200
  @min_items = options[:min_items] || 5
  @options = options
  @logger = options[:logger] || Rails.logger
end

Instance Method Details

#always_add_store_itemsObject



68
69
70
71
72
73
74
75
76
77
# File 'app/services/item/cycle_count_scheduler.rb', line 68

def always_add_store_items
  # if we're in the first week of the month add the monthly and weekly items, else just add the weekly items
  add_options = (1..7).cover?(Date.current.day) ? %w[weekly monthly] : ['weekly']
  StoreItem.joins(item: :product_category)
           .merge(Item.warehouse)
           .merge(ProductCategory.non_publications)
           .where(store_id: 1, location: 'AVAILABLE', always_add_to_cycle_count: add_options, is_discontinued: false, items: {
                    is_discontinued: false, is_kit: false
                  })
end

#potential_store_itemsObject



59
60
61
62
63
64
65
66
# File 'app/services/item/cycle_count_scheduler.rb', line 59

def potential_store_items
  StoreItem.joins(item: %i[primary_product_line product_category])
           .merge(Item.warehouse)
           .merge(ProductCategory.non_publications)
           .where(store_id: @store.id, location: 'AVAILABLE', is_discontinued: false, items: { is_discontinued: false,
                                                                                               is_kit: false })
           .order('cycle_count_priority DESC, product_lines.lineage_expanded ASC, product_categories.lineage_expanded ASC'.sql_safe)
end

#processObject



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
# File 'app/services/item/cycle_count_scheduler.rb', line 19

def process
  cycle_count = CycleCount.new(store_id: @store.id, due_date: @due_date, marketing_only: false)

  # check for items which should always be added to the count
  always_add_store_items.each do |si|
    # check if it's not already pending to count
    unless CycleCountItem.joins(:cycle_count).where(cycle_counts: { store_id: @store.id }, state: 'draft', location: si.location,
                                                    item_id: si.item_id).any?
      cycle_count.cycle_count_items.build(item_id: si.item_id, location: si.location, storage_location_ids: si.storage_location_ids)
    end
  end

  items_count = 0

  potential_store_items.limit(@max_items).each do |si|
    # check if it's not already pending to count
    item_exist_in_draft = CycleCountItem.joins(:cycle_count).
                            where(cycle_counts: { store_id: @store.id },
                                  state: 'draft',
                                  location: si.location,
                                  item_id: si.item_id).present?
    unless item_exist_in_draft
      cycle_count.cycle_count_items.build(item_id: si.item_id,
                                          location: si.location,
                                          storage_location_ids: si.storage_location_ids)
    end
    si.update_attribute(:add_to_next_cycle_count, false) if si.add_to_next_cycle_count?
  end

  if cycle_count.cycle_count_items.present?
    cycle_count.save!
    cycle_count.add_all_group_items

    return { scheduled: true, cycle_count: cycle_count }.freeze
  else
    ErrorReporting.error("Cycle Count Scheduler for store #{@store.id} Found No Items, this is abnormal")
    return { scheduled: false, message: "No Items"}
  end
end