Class: SolidusAdmin::StockItems::Index::Component

Inherits:
BaseComponent
  • Object
show all
Includes:
Layout::PageHelpers
Defined in:
app/components/solidus_admin/stock_items/index/component.rb

Instance Method Summary collapse

Constructor Details

#initialize(page:) ⇒ Component



6
7
8
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 6

def initialize(page:)
  @page = page
end

Instance Method Details

#back_orderable_columnObject



158
159
160
161
162
163
164
165
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 158

def back_orderable_column
  {
    header: :back_orderable,
    data: ->(stock_item) do
      stock_item.backorderable? ? component('ui/badge').yes : component('ui/badge').no
    end
  }
end

#batch_actionsObject



22
23
24
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 22

def batch_actions
  []
end

#columnsObject



65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 65

def columns
  [
    image_column,
    name_column,
    sku_column,
    variant_column,
    stock_location_column,
    back_orderable_column,
    count_on_hand_column,
    stock_movements_column,
  ]
end

#count_on_hand_columnObject



167
168
169
170
171
172
173
174
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 167

def count_on_hand_column
  {
    header: :count_on_hand,
    data: ->(stock_item) do
       :div, stock_item.count_on_hand
    end
  }
end

#filtersObject



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
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 36

def filters
  [
    {
      presentation: t('.filters.stock_locations'),
      combinator: 'or',
      attribute: "stock_location_id",
      predicate: "eq",
      options: Spree::StockLocation.all.map do |stock_location|
        [
          stock_location.name.titleize,
          stock_location.id
        ]
      end
    },
    {
      presentation: t('.filters.variants'),
      combinator: 'or',
      attribute: "variant_id",
      predicate: "eq",
      options: Spree::Variant.all.map do |variant|
        [
          variant.descriptive_name,
          variant.id
        ]
      end
    },
  ]
end

#image_columnObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 78

def image_column
  {
    col: { class: "w-[72px]" },
    header: tag.span('aria-label': Spree::Image.model_name.human, role: 'text'),
    data: ->(stock_item) do
      image = stock_item.variant.gallery.images.first or return

      render(
        component('ui/thumbnail').new(
          src: image.url(:small),
          alt: stock_item.variant.name
        )
      )
    end
  }
end

#name_columnObject



95
96
97
98
99
100
101
102
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 95

def name_column
  {
    header: :name,
    data: ->(stock_item) do
       :div, stock_item.variant.name
    end
  }
end

#next_page_pathObject



18
19
20
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 18

def next_page_path
  solidus_admin.url_for(**request.params, page: @page.next_param, only_path: true) unless @page.last?
end

#permitted_query_paramsObject



176
177
178
179
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 176

def permitted_query_params
  return params[:q].permit! if params[:q].respond_to?(:permit)
  {}
end

#prev_page_pathObject



14
15
16
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 14

def prev_page_path
  solidus_admin.url_for(**request.params, page: @page.number - 1, only_path: true) unless @page.first?
end

#scopesObject



26
27
28
29
30
31
32
33
34
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 26

def scopes
  [
    { label: t('.scopes.all_stock_items'), name: 'all', default: true },
    { label: t('.scopes.back_orderable'), name: 'back_orderable' },
    { label: t('.scopes.out_of_stock'), name: 'out_of_stock' },
    { label: t('.scopes.low_stock'), name: 'low_stock' },
    { label: t('.scopes.in_stock'), name: 'in_stock' },
  ]
end

#sku_columnObject



104
105
106
107
108
109
110
111
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 104

def sku_column
  {
    header: :sku,
    data: ->(stock_item) do
       :div, stock_item.variant.sku
    end
  }
end

#stock_location_columnObject



128
129
130
131
132
133
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 128

def stock_location_column
  {
    header: :stock_location,
    data: ->(stock_item) { stock_item.stock_location.name },
  }
end

#stock_movement_countsObject

Cache the stock movement counts to avoid N+1 queries



136
137
138
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 136

def stock_movement_counts
  @stock_movement_counts ||= Spree::StockMovement.where(stock_item_id: @page.records.ids).group(:stock_item_id).count
end

#stock_movements_columnObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 140

def stock_movements_column
  {
    header: :stock_movements,
    data: -> do
      count = stock_movement_counts[_1.id] || 0

      link_to(
        "#{count} #{Spree::StockMovement.model_name.human(count: count).downcase}",
        spree.admin_stock_location_stock_movements_path(
          _1.stock_location.id,
          q: { variant_sku_eq: _1.variant.sku },
        ),
        class: 'body-link'
      )
    end
  }
end

#titleObject



10
11
12
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 10

def title
  Spree::StockItem.model_name.human.pluralize
end

#variant_columnObject



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/components/solidus_admin/stock_items/index/component.rb', line 113

def variant_column
  {
    header: :variant,
    data: ->(stock_item) do
      (:div, class: "space-y-0.5") do
        safe_join(
          stock_item.variant.option_values.sort_by(&:option_type_name).map do |option_value|
            render(component('ui/badge').new(name: "#{option_value.option_type_presentation}: #{option_value.presentation}"))
          end
        )
      end
    end
  }
end