Skip to content

Commit d908c21

Browse files
committed
feat: Add export product drive participants button to the product drive show view
1 parent 3b24d37 commit d908c21

4 files changed

Lines changed: 88 additions & 0 deletions

File tree

app/controllers/product_drives_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ def show
7474
@selected_name_filter = filter_params[:by_name]
7575
@selected_item_category = filter_params[:by_item_category_id]
7676
@product_drive = current_organization.product_drives.includes(:donations).find(params[:id])
77+
78+
respond_to do |format|
79+
format.html
80+
format.csv do
81+
send_data Exports::ExportProductDriveParticipantsCSVService.new(
82+
@product_drive
83+
).generate_csv, filename: "Product-Drive-Participants-#{@product_drive.name}-#{Time.zone.today}.csv"
84+
end
85+
end
7786
end
7887

7988
def update
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module Exports
2+
class ExportProductDriveParticipantsCSVService
3+
include ItemsHelper
4+
5+
HEADERS = ["Donation Id", "Product Drive Participant", "Storage Location", "Quantity", "In Kind Value"].freeze
6+
7+
def initialize(product_drive)
8+
@product_drive = product_drive
9+
end
10+
11+
def generate_csv
12+
CSV.generate do |csv|
13+
csv << generate_headers
14+
15+
product_drive.donations.includes(:product_drive_participant).find_each do |donation|
16+
csv << generate_row(donation)
17+
end
18+
end
19+
end
20+
21+
private
22+
23+
attr_reader :product_drive
24+
25+
def generate_row(donation)
26+
[
27+
donation.id.to_s,
28+
donation.product_drive_participant_id ? donation.product_drive_participant.business_name : nil,
29+
donation.storage_location.name,
30+
donation.line_items.count(&:quantity),
31+
dollar_value(donation.value_per_itemizable)
32+
]
33+
end
34+
35+
def generate_headers
36+
HEADERS
37+
end
38+
end
39+
end

app/views/product_drives/show.html.erb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@
9595
To add additional donations to this product drive, please edit that donation and select this product drive from the appropriate dropdown.
9696
</p>
9797
<!-- /.card-footer-->
98+
<div class="card-footer">
99+
<span class="float-right">
100+
<%=
101+
if @product_drive.donations.length > 0
102+
download_button_to(
103+
product_drive_path(@product_drive, format: :csv),
104+
text: "Export Product Drive Participants"
105+
)
106+
end
107+
%>
108+
</span>
109+
</div>
98110
</div>
99111
<!-- /.card -->
100112
</div>

spec/requests/product_drives_requests_spec.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,34 @@
291291

292292
expect(response.body).to include("4862167")
293293
end
294+
295+
context "csv" do
296+
it 'is successful' do
297+
product_drive = create(:product_drive, organization: organization)
298+
299+
get product_drive_path(id: product_drive.id, format: :csv)
300+
301+
expect(response).to be_successful
302+
expect(response.header['Content-Type']).to include 'text/csv'
303+
304+
expected_headers = Exports::ExportProductDriveParticipantsCSVService::HEADERS
305+
expect(response.body.chomp.split(",")).to eq(expected_headers)
306+
end
307+
308+
it 'returns ONLY the associated product drive participants' do
309+
product_drive = create(:product_drive, organization: organization)
310+
participant = create(:product_drive_participant, business_name: "Associated Participant")
311+
create(:donation, product_drive: product_drive, product_drive_participant: participant)
312+
313+
other_participant = create(:product_drive_participant, business_name: "Unassociated Participant")
314+
create(:donation, product_drive: create(:product_drive, organization: organization), product_drive_participant: other_participant)
315+
316+
get product_drive_path(id: product_drive.id, format: :csv)
317+
318+
expect(response.body).to include("Associated Participant")
319+
expect(response.body).not_to include("Unassociated Participant")
320+
end
321+
end
294322
end
295323

296324
describe "DELETE #destroy" do

0 commit comments

Comments
 (0)