-
-
Notifications
You must be signed in to change notification settings - Fork 573
Expand file tree
/
Copy pathexport_request_service.rb
More file actions
119 lines (98 loc) · 2.98 KB
/
export_request_service.rb
File metadata and controls
119 lines (98 loc) · 2.98 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
module Exports
class ExportRequestService
DELETED_ITEMS_COLUMN_HEADER = '<DELETED_ITEMS>'.freeze
def initialize(requests)
@requests = requests.includes(:partner, {item_requests: :item})
end
def generate_csv
csv_data = generate_csv_data
CSV.generate(headers: true) do |csv|
csv_data.each { |row| csv << row }
end
end
def generate_csv_data
csv_data = []
csv_data << headers
requests.each do |request|
csv_data << build_row_data(request)
end
csv_data
end
private
attr_reader :requests
def headers
# Build the headers in the correct order
base_headers + item_headers
end
def headers_with_indexes
@headers_with_indexes ||= headers.each_with_index.to_h
end
def base_table
{
"Date" => ->(request) {
request.created_at.strftime("%m/%d/%Y")
},
"Requestor" => ->(request) {
request.partner.name
},
"Type" => ->(request) {
request.request_type&.humanize
},
"Status" => ->(request) {
request.status.humanize
}
}
end
def base_headers
base_table.keys
end
def item_headers
@item_headers ||= compute_item_headers
end
def compute_item_headers
# This reaches into the item, handling invalid deleted items
item_names = Set.new
all_item_requests.each do |item_request|
if item_request.item
item = item_request.item
item_names << item.name
item.request_units.each do |unit|
item_names << "#{item.name} - #{unit.name.pluralize}"
end
# It's possible that the unit is no longer valid, so we'd
# add that individually
if item_request.request_unit.present?
item_names << "#{item.name} - #{item_request.request_unit.pluralize}"
end
end
end
# Adding this to handle cases in which a requested item
# has been deleted. Normally this wouldn't be necessary,
# but previous versions of the application would cause
# this orphaned data
item_names.sort.uniq << DELETED_ITEMS_COLUMN_HEADER
end
def build_row_data(request)
row = base_table.values.map { |closure| closure.call(request) }
row += Array.new(item_headers.size, 0)
request.item_requests.each do |item_request|
item_name = if item_request.item.present?
if item_request.request_unit.present?
item_request.name_with_unit(0)
else
item_request.item.name
end
else
DELETED_ITEMS_COLUMN_HEADER
end
item_column_idx = headers_with_indexes[item_name]
row[item_column_idx] ||= 0
row[item_column_idx] += item_request.quantity.to_i
end
row
end
def all_item_requests
@all_item_requests ||= Partners::ItemRequest.where(request: requests).includes(item: :request_units)
end
end
end