Class: Www::StockStatusPresenter

Inherits:
Object
  • Object
show all
Defined in:
app/presenters/www/stock_status_presenter.rb

Overview

Presents stock status information with tiered messaging for product pages

Provides:

  • Tiered urgency messaging based on quantity thresholds
  • Visual status indicators (color classes)
  • Estimated ship dates based on warehouse location
  • Low stock warnings using item-level thresholds

Usage:
presenter = Www::StockStatusPresenter.new(view_product_catalog, catalog_item)
presenter.status_tier # => :in_stock, :low_stock, :very_low, :out_of_stock
presenter.message # => "Only 3 left - order soon!"
presenter.to_h # => Full hash for JSON API response

rubocop:disable Metrics/ClassLength

Constant Summary collapse

DEFAULT_LOW_STOCK_THRESHOLD =

Thresholds for stock tiers (can be overridden by item.qty_warn_on_stock)

10
VERY_LOW_STOCK_THRESHOLD =
3
PRIVACY_THRESHOLD =

Don't show exact quantity above this

10

Instance Attribute Summary collapse

Delegated Instance Attributes collapse

Instance Method Summary collapse

Constructor Details

#initialize(view_product_catalog, catalog_item = nil) ⇒ StockStatusPresenter

Returns a new instance of StockStatusPresenter.



30
31
32
33
34
# File 'app/presenters/www/stock_status_presenter.rb', line 30

def initialize(view_product_catalog, catalog_item = nil)
  @view_product_catalog = view_product_catalog
  @catalog_item = catalog_item || view_product_catalog.catalog_item
  @item = @catalog_item&.item
end

Instance Attribute Details

#catalog_itemObject (readonly)

Returns the value of attribute catalog_item.



25
26
27
# File 'app/presenters/www/stock_status_presenter.rb', line 25

def catalog_item
  @catalog_item
end

#itemObject (readonly)

Returns the value of attribute item.



25
26
27
# File 'app/presenters/www/stock_status_presenter.rb', line 25

def item
  @item
end

#view_product_catalogObject (readonly)

Returns the value of attribute view_product_catalog.



25
26
27
# File 'app/presenters/www/stock_status_presenter.rb', line 25

def view_product_catalog
  @view_product_catalog
end

Instance Method Details

#business_days_to_fulfillObject

Alias for View_product_catalog#business_days_to_fulfill

Returns:

  • (Object)

    View_product_catalog#business_days_to_fulfill

See Also:



27
28
# File 'app/presenters/www/stock_status_presenter.rb', line 27

delegate :store_item_qty_available, :business_days_to_fulfill, :product_stock_status,
:item_sku, to: :view_product_catalog

#color_classString

CSS class for visual indicator

Returns:

  • (String)

    Bootstrap-compatible color class



83
84
85
86
87
88
89
90
91
92
# File 'app/presenters/www/stock_status_presenter.rb', line 83

def color_class
  case status_tier
  when :in_stock then 'text-success'
  when :low_stock then 'text-warning'
  when :very_low then 'text-danger'
  when :alternate_warehouse then 'text-info'
  when :out_of_stock, :backordered then 'text-muted'
  else 'text-secondary'
  end
end

#display_quantityInteger?

Available quantity (for display, respects privacy threshold)

Returns:

  • (Integer, nil)


122
123
124
125
126
# File 'app/presenters/www/stock_status_presenter.rb', line 122

def display_quantity
  return nil unless show_quantity?

  available_quantity
end

#expected_dateDate?

Expected availability date for out-of-stock items

Returns:

  • (Date, nil)


154
155
156
157
158
159
# File 'app/presenters/www/stock_status_presenter.rb', line 154

def expected_date
  return nil if product_available?
  return @expected_date if defined?(@expected_date)

  @expected_date = catalog_item&.next_available&.dig(:next_available_date)
end

#expected_soon?Boolean

Is stock expected soon (within 30 days)?

Returns:

  • (Boolean)


163
164
165
# File 'app/presenters/www/stock_status_presenter.rb', line 163

def expected_soon?
  expected_date && expected_date <= 30.days.from_now
end

#iconString

Icon for status indicator

Returns:

  • (String)

    Font Awesome icon name



96
97
98
99
100
101
102
103
104
105
106
# File 'app/presenters/www/stock_status_presenter.rb', line 96

def icon
  case status_tier
  when :in_stock then 'fa-circle-check'
  when :low_stock then 'fa-clock'
  when :very_low then 'fa-exclamation-triangle'
  when :alternate_warehouse then 'fa-truck'
  when :out_of_stock then 'fa-circle-xmark'
  when :backordered then 'fa-hourglass-half'
  else 'fa-question-circle'
  end
end

#item_skuObject

Alias for View_product_catalog#item_sku

Returns:

  • (Object)

    View_product_catalog#item_sku

See Also:



27
28
# File 'app/presenters/www/stock_status_presenter.rb', line 27

delegate :store_item_qty_available, :business_days_to_fulfill, :product_stock_status,
:item_sku, to: :view_product_catalog

#labelString

Short status label for badges/icons

Returns:

  • (String)


71
72
73
74
75
76
77
78
79
# File 'app/presenters/www/stock_status_presenter.rb', line 71

def label
  case status_tier
  when :in_stock, :alternate_warehouse then 'In Stock'
  when :low_stock, :very_low then 'Low Stock'
  when :out_of_stock then 'Out of Stock'
  when :backordered then 'Backordered'
  else 'Unknown'
  end
end

#messageString

User-facing message based on stock tier

Returns:

  • (String)

    Display message for the product page



57
58
59
60
61
62
63
64
65
66
67
# File 'app/presenters/www/stock_status_presenter.rb', line 57

def message
  case status_tier
  when :in_stock then "In Stock, #{ship_message}"
  when :low_stock then "Only #{available_quantity} left, #{ship_message}"
  when :very_low then "Last #{available_quantity} in stock! #{ship_message}"
  when :alternate_warehouse then 'In Stock - Ships in 2-3 business days'
  when :out_of_stock then out_of_stock_message
  when :backordered then backordered_message
  else 'Check availability'
  end
end

#product_stock_statusObject

Alias for View_product_catalog#product_stock_status

Returns:

  • (Object)

    View_product_catalog#product_stock_status

See Also:



27
28
# File 'app/presenters/www/stock_status_presenter.rb', line 27

delegate :store_item_qty_available, :business_days_to_fulfill, :product_stock_status,
:item_sku, to: :view_product_catalog

#ship_messageString

Shipping estimate message

Returns:

  • (String)


130
131
132
133
134
135
136
137
138
139
140
# File 'app/presenters/www/stock_status_presenter.rb', line 130

def ship_message
  days = business_days_to_fulfill.to_i

  if days.zero?
    ships_freight? ? 'Ships Next Business Day' : 'Same Day Shipping or Pickup'
  elsif days == 1
    'Ships Tomorrow'
  else
    "Ships in #{days} Business Days"
  end
end

#shipping_infoHash

Full shipping info with icon

Returns:

  • (Hash)


144
145
146
147
148
149
150
# File 'app/presenters/www/stock_status_presenter.rb', line 144

def shipping_info
  {
    text: "In Stock, #{ship_message}",
    icon: shipping_icon,
    days_to_fulfill: business_days_to_fulfill.to_i
  }
end

#show_quantity?Boolean

Should we show the exact quantity?

Returns:

  • (Boolean)

    Only show for low stock situations



116
117
118
# File 'app/presenters/www/stock_status_presenter.rb', line 116

def show_quantity?
  show_urgency? && available_quantity <= PRIVACY_THRESHOLD
end

#show_urgency?Boolean

Should we show urgency styling?

Returns:

  • (Boolean)


110
111
112
# File 'app/presenters/www/stock_status_presenter.rb', line 110

def show_urgency?
  %i[low_stock very_low].include?(status_tier)
end

#status_tierSymbol

Main status tier determination

Returns:

  • (Symbol)

    :in_stock, :low_stock, :very_low, :alternate_warehouse, :out_of_stock, :backordered



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/presenters/www/stock_status_presenter.rb', line 38

def status_tier
  return :out_of_stock unless product_available?

  qty = available_quantity
  warn_threshold = low_stock_threshold

  if qty <= 0
    alternate_available? ? :alternate_warehouse : :out_of_stock
  elsif qty <= VERY_LOW_STOCK_THRESHOLD
    :very_low
  elsif qty <= warn_threshold
    :low_stock
  else
    :in_stock
  end
end

#store_item_qty_availableObject

Alias for View_product_catalog#store_item_qty_available

Returns:

  • (Object)

    View_product_catalog#store_item_qty_available

See Also:



27
28
# File 'app/presenters/www/stock_status_presenter.rb', line 27

delegate :store_item_qty_available, :business_days_to_fulfill, :product_stock_status,
:item_sku, to: :view_product_catalog

#to_hHash

Full hash representation for JSON API

Returns:

  • (Hash)


169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/presenters/www/stock_status_presenter.rb', line 169

def to_h
  {
    status: status_tier.to_s,
    available: product_available?,
    quantity: display_quantity,
    message: message,
    label: label,
    color_class: color_class,
    icon: icon,
    show_urgency: show_urgency?,
    ships_from: ships_from_warehouse,
    estimated_ship_date: estimated_ship_date&.iso8601,
    expected_restock_date: expected_date&.iso8601,
    expected_soon: expected_soon?
  }.compact
end