Skip to content

Commit cf686c1

Browse files
seabeeberryseabeeberry
authored andcommitted
Implemented ItemizedRequestBreakdownService using class-level methods
1 parent 87b581f commit cf686c1

File tree

3 files changed

+61
-80
lines changed

3 files changed

+61
-80
lines changed

app/controllers/reports_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def activity_graph
4141

4242
def itemized_requests
4343
requests = current_organization.requests.during(helpers.selected_range)
44-
@itemized_request_data = RequestItemizedBreakdownService.new(organization: current_organization, request_ids: requests.pluck(:id)).fetch
44+
@itemized_request_data = RequestItemizedBreakdownService.call(organization: current_organization, request_ids: requests.pluck(:id))
4545
end
4646

4747
private
Lines changed: 54 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,70 @@
11
class RequestItemizedBreakdownService
2-
#
3-
# Initializes the RequestItemizedBreakdownService whose
4-
# purpose is to construct an itemized breakdown of requested items
5-
#
6-
# @param organization [Organization]
7-
# @param request_ids [Array<Integer>]
8-
# @return [RequestItemizedBreakdownService]
9-
def initialize(organization:, request_ids:)
10-
@organization = organization
11-
@request_ids = request_ids
12-
end
2+
class << self
3+
def call(organization:, request_ids:, format: :hash)
4+
data = fetch(organization: organization, request_ids: request_ids)
5+
(format == :csv) ? convert_to_csv(data) : data
6+
end
137

14-
#
15-
# Returns a hash containing the itemized breakdown of
16-
# requested items.
17-
#
18-
# @return [Array]
19-
def fetch
20-
inventory = View::Inventory.new(@organization.id)
21-
current_onhand = current_onhand_quantities(inventory)
22-
current_min_onhand = current_onhand_minimums(inventory)
23-
items_requested = fetch_items_requested
8+
def fetch(organization:, request_ids:)
9+
inventory = View::Inventory.new(organization.id)
10+
current_onhand = current_onhand_quantities(inventory)
11+
current_min_onhand = current_onhand_minimums(inventory)
12+
items_requested = fetch_items_requested(organization: organization, request_ids: request_ids)
2413

25-
items_requested.each do |item|
26-
name = item[:name]
14+
items_requested.each do |item|
15+
name = item[:name]
2716

28-
on_hand = current_onhand[name]
29-
minimum = current_min_onhand[name]
30-
below_onhand_minimum = on_hand && minimum && on_hand < minimum
17+
on_hand = current_onhand[name]
18+
minimum = current_min_onhand[name]
19+
below_onhand_minimum = on_hand && minimum && on_hand < minimum
3120

32-
item.merge!(
33-
on_hand: on_hand,
34-
onhand_minimum: minimum,
35-
below_onhand_minimum: below_onhand_minimum
36-
)
37-
end
38-
39-
items_requested.sort_by { |item| [item[:name], item[:unit].to_s] }
40-
end
21+
item.merge!(
22+
on_hand: on_hand,
23+
onhand_minimum: minimum,
24+
below_onhand_minimum: below_onhand_minimum
25+
)
26+
end
4127

42-
#
43-
# Returns a CSV string representation of the itemized breakdown of
44-
# what was requested
45-
#
46-
# @return [String]
47-
def fetch_csv
48-
convert_to_csv(fetch)
49-
end
28+
items_requested.sort_by { |item| [item[:name], item[:unit].to_s] }
29+
end
5030

51-
private
31+
def csv(organization:, request_ids:)
32+
convert_to_csv(fetch(organization: organization, request_ids: request_ids))
33+
end
5234

53-
attr_reader :organization, :request_ids
35+
private
5436

55-
def current_onhand_quantities(inventory)
56-
inventory.all_items.group_by(&:name).to_h { |k, v| [k, v.sum { |r| r.quantity.to_i }] }
57-
end
37+
def current_onhand_quantities(inventory)
38+
inventory.all_items.group_by(&:name).to_h { |k, v| [k, v.sum { |r| r.quantity.to_i }] }
39+
end
5840

59-
def current_onhand_minimums(inventory)
60-
inventory.all_items.group_by(&:name).to_h { |k, v| [k, v.map(&:on_hand_minimum_quantity).compact.max] }
61-
end
41+
def current_onhand_minimums(inventory)
42+
inventory.all_items.group_by(&:name).to_h { |k, v| [k, v.map(&:on_hand_minimum_quantity).compact.max] }
43+
end
6244

63-
def fetch_items_requested
64-
Partners::ItemRequest
65-
.includes(:item)
66-
.where(partner_request_id: @request_ids)
67-
.group_by { |ir| [ir.item_id, ir.request_unit] }
68-
.map do |(item_id, unit), grouped|
69-
item = grouped.first.item
70-
{
71-
item_id: item.id,
72-
name: item.name,
73-
unit: unit,
74-
quantity: grouped.sum { |ri| ri.quantity.to_i }
75-
}
76-
end
77-
end
45+
def fetch_items_requested(organization:, request_ids:)
46+
Partners::ItemRequest
47+
.includes(:item)
48+
.where(partner_request_id: request_ids)
49+
.group_by { |ir| [ir.item_id, ir.request_unit] }
50+
.map do |(item_id, unit), grouped|
51+
item = grouped.first.item
52+
{
53+
item_id: item.id,
54+
name: item.name,
55+
unit: unit,
56+
quantity: grouped.sum { |ri| ri.quantity.to_i }
57+
}
58+
end
59+
end
7860

79-
def convert_to_csv(items_requested_data)
80-
CSV.generate do |csv|
81-
csv << ["Item", "Total Requested", "Total On Hand"]
82-
items_requested_data.each do |item|
83-
csv << [item[:name], item[:quantity], item[:on_hand]]
61+
def convert_to_csv(items_requested_data)
62+
CSV.generate do |csv|
63+
csv << ["Item", "Total Requested", "Total On Hand"]
64+
items_requested_data.each do |item|
65+
csv << [item[:name], item[:quantity], item[:on_hand]]
66+
end
8467
end
8568
end
8669
end
87-
88-
def inventory
89-
@inventory ||= View::Inventory.new(@organization.id)
90-
end
9170
end

spec/services/request_itemized_breakdown_service_spec.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
end
2323

2424
describe "#fetch" do
25-
subject(:result) { service.fetch }
26-
let(:service) { described_class.new(organization: organization, request_ids: [request_1.id, request_2.id]) }
25+
subject(:result) do
26+
described_class.call(organization: organization, request_ids: [request_1.id, request_2.id])
27+
end
2728

2829
it "should include the break down of requested items" do
2930
expected_output = [
@@ -35,8 +36,9 @@
3536
end
3637

3738
describe "#fetch_csv" do
38-
subject(:subject) { service.fetch_csv }
39-
let(:service) { described_class.new(organization: organization, request_ids: [request_1.id, request_2.id]) }
39+
subject(:subject) do
40+
described_class.call(organization: organization, request_ids: [request_1.id, request_2.id], format: :csv)
41+
end
4042

4143
it "should output the expected output but in CSV format" do
4244
expected_csv = <<~CSV

0 commit comments

Comments
 (0)