Class: Item::CycleCountScheduler

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

Overview

Service object: cycle count scheduler.

Instance Attribute Summary

Attributes inherited from BaseService

#options

Instance Method Summary collapse

Methods inherited from BaseService

#log_debug, #log_error, #log_info, #log_warning, #logger, #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



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

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



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

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



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

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



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

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

  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

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