-
-
Notifications
You must be signed in to change notification settings - Fork 571
Expand file tree
/
Copy pathitems_controller.rb
More file actions
220 lines (186 loc) · 6.74 KB
/
items_controller.rb
File metadata and controls
220 lines (186 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# Provides full CRUD to Items. Every item is rooted in a BaseItem, but Diaperbanks have full control to do whatever
# they like with their own Items.
class ItemsController < ApplicationController
def index
@items = current_organization
.items
.includes(:kit, :line_items, :request_units, :item_category)
.alphabetized
.class_filter(filter_params)
.group('items.id')
@items = @items.active unless params[:include_inactive_items]
@item_categories = current_organization.item_categories.includes(:items).order('name ASC')
@kits = current_organization.kits.includes(line_items: :item)
@storages = current_organization.storage_locations.active.order(id: :asc)
@include_inactive_items = params[:include_inactive_items]
@selected_reporting_category = filter_params[:by_reporting_category]
@paginated_items = @items.page(params[:page])
@inventory = View::Inventory.new(current_organization.id)
@items_by_storage_collection_and_quantity = ItemsByStorageCollectionAndQuantityQuery.call(organization: current_organization,
inventory: @inventory,
filter_params: filter_params)
respond_to do |format|
format.html
format.csv { send_data Item.generate_csv_from_inventory(@items, @inventory), filename: "Items-#{Time.zone.today}.csv" }
end
end
def create
create = if Flipper.enabled?(:enable_packs)
ItemCreateService.new(organization_id: current_organization.id, item_params: item_params, request_unit_ids:)
else
ItemCreateService.new(organization_id: current_organization.id, item_params: item_params)
end
result = create.call
if result.success?
redirect_to items_path, notice: "#{result.value.name} added!"
else
# Define a @item to be used in the `new` action to be rendered with
# the provided parameters. This is required to render the page again
# with the error + the invalid parameters.
@item_categories = current_organization.item_categories.order('name ASC') # Load categories here
@item = current_organization.items.new(item_params)
flash.now[:error] = result.error.record.errors.full_messages.to_sentence
render action: :new
end
end
def new
@item_categories = current_organization.item_categories
@item = current_organization.items.new
end
def edit
@item_categories = current_organization.item_categories
@item = current_organization.items.find(params[:id])
@reporting_category_hint = reporting_category_hint
end
def show
@item = current_organization.items.find(params[:id])
@inventory = View::Inventory.new(current_organization.id)
storage_location_ids = @inventory.storage_locations_for_item(@item.id)
@storage_locations_containing = StorageLocation.find(storage_location_ids)
@barcodes_for = BarcodeItem.where(barcodeable_id: @item.id)
@reporting_category_hint = reporting_category_hint
end
def update
@item = current_organization.items.find(params[:id])
@item.attributes = item_params
deactivated = @item.active_changed? && !@item.active
if deactivated && !@item.can_deactivate?
flash.now[:error] = "Can't deactivate this item - it is currently assigned to either an active kit or a storage location!"
render action: :edit
return
end
if update_item
redirect_to items_path, notice: "#{@item.name} updated!"
else
flash.now[:error] = "Something didn't work quite right -- try again? #{@item.errors.map { |error| "#{error.attribute}: #{error.message}" }}"
render action: :edit
end
end
def deactivate
item = current_organization.items.find(params[:id])
begin
item.deactivate!
rescue => e
flash[:error] = e.message
redirect_back(fallback_location: items_path)
return
end
flash[:notice] = "#{item.name} has been deactivated."
redirect_to items_path
end
def destroy
item = current_organization.items.find(params[:id])
item.destroy
if item.errors.any?
flash[:error] = item.errors.full_messages.join("\n")
redirect_back(fallback_location: items_path)
return
end
flash[:notice] = "#{item.name} has been removed."
redirect_to items_path
end
def restore
item = current_organization.items.find(params[:id])
ActiveRecord::Base.transaction do
Item.reactivate([item.id])
end
flash[:notice] = "#{item.name} has been restored."
redirect_to items_path
end
def remove_category
item = current_organization.items.find(params[:id])
previous_category = item.item_category
item.update!(item_category: nil)
flash[:notice] = "#{item.name} has been removed from #{previous_category.name}."
redirect_to item_category_path(previous_category)
end
private
def reporting_category_hint
item = current_organization.items.find(params[:id])
if item.kit_id
"Kits are reported based on their contents."
end
end
def clean_item_value_in_cents
return unless params[:item][:value_in_cents]
params[:item][:value_in_cents] = params[:item][:value_in_cents].gsub(/[$,.]/, "")
end
def clean_item_value_in_dollars
return unless params[:item][:value_in_dollars]
params[:item][:value_in_cents] = params[:item][:value_in_dollars].gsub(/[$,]/, "").to_d * 100
params[:item].delete(:value_in_dollars)
end
def item_params
# Memoize the value of this to prevent trying to
# clean the values again which would result in an
# error.
return @item_params if @item_params
clean_item_value_in_cents
clean_item_value_in_dollars
@item_params = params.require(:item).permit(
:name,
:item_category_id,
:reporting_category,
:partner_key,
:value_in_cents,
:package_size,
:on_hand_minimum_quantity,
:on_hand_recommended_quantity,
:distribution_quantity,
:visible_to_partners,
:active,
:additional_info,
:unit_request_limit
)
end
def request_unit_ids
params.require(:item).permit(unit_ids: []).fetch(:unit_ids, []).compact_blank
end
def request_unit_limits
(params.require(:item).permit(unit_limits: {})[:unit_limits] || {}).to_h
end
# We need to update both the item and the request_units together and fail together
def update_item
if Flipper.enabled?(:enable_packs)
update_item_and_request_units
else
@item.save
end
end
def update_item_and_request_units
begin
Item.transaction do
@item.save!
@item.sync_request_units!(request_unit_ids, request_unit_limits)
end
rescue
return false
end
true
end
helper_method \
def filter_params(_parameters = nil)
return {} unless params.key?(:filters)
params.require(:filters).permit(:by_reporting_category, :include_inactive_items)
end
end