Skip to content

Commit

Permalink
Merge pull request #4070 from katelovescode/github-3388/all_items_in_…
Browse files Browse the repository at this point in the history
…export

Adds query for all an organization's items to the CSV export service, updates spec to test new behavior
  • Loading branch information
cielf committed Feb 15, 2024
2 parents db840ac + 6363371 commit 404dff3
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 21 deletions.
2 changes: 1 addition & 1 deletion app/controllers/distributions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def index
respond_to do |format|
format.html
format.csv do
send_data Exports::ExportDistributionsCSVService.new(distributions: @distributions, filters: filter_params).generate_csv, filename: "Distributions-#{Time.zone.today}.csv"
send_data Exports::ExportDistributionsCSVService.new(distributions: @distributions, organization: current_organization, filters: filter_params).generate_csv, filename: "Distributions-#{Time.zone.today}.csv"
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/partners_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def show
respond_to do |format|
format.html
format.csv do
send_data Exports::ExportDistributionsCSVService.new(distributions: @partner_distributions, filters: filter_params).generate_csv, filename: "PartnerDistributions-#{Time.zone.today}.csv"
send_data Exports::ExportDistributionsCSVService.new(distributions: @partner_distributions, organization: current_organization, filters: filter_params).generate_csv, filename: "PartnerDistributions-#{Time.zone.today}.csv"
end
end
end
Expand Down
15 changes: 5 additions & 10 deletions app/services/exports/export_distributions_csv_service.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Exports
class ExportDistributionsCSVService
include DistributionHelper
def initialize(distributions:, filters: [])
def initialize(distributions:, organization:, filters: [])
# Currently, the @distributions are already loaded by the controllers that are delegating exporting
# to this service object; this is happening within the same request/response cycle, so it's already
# in memory, so we can pass that collection in directly. Should this be moved to a background / async
Expand All @@ -10,6 +10,7 @@ def initialize(distributions:, filters: [])
# service object.
@distributions = distributions
@filters = filters
@organization = organization
end

def generate_csv
Expand Down Expand Up @@ -114,15 +115,7 @@ def base_headers
def item_headers
return @item_headers if @item_headers

item_names = Set.new

distributions.each do |distribution|
distribution.line_items.each do |line_item|
item_names.add(line_item.item.name)
end
end

@item_headers = item_names.sort
@item_headers = @organization.items.order(:created_at).distinct.select([:created_at, :name]).map(&:name)
end

def build_row_data(distribution)
Expand All @@ -133,6 +126,8 @@ def build_row_data(distribution)
distribution.line_items.each do |line_item|
item_name = line_item.item.name
item_column_idx = headers_with_indexes[item_name]
next unless item_column_idx

row[item_column_idx] += line_item.quantity
end

Expand Down
64 changes: 55 additions & 9 deletions spec/services/exports/export_distributions_csv_service_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
describe Exports::ExportDistributionsCSVService do
describe '#generate_csv_data' do
subject { described_class.new(distributions: distributions, filters: filters).generate_csv_data }
subject { described_class.new(distributions: distributions, organization: Organization.first, filters: filters).generate_csv_data }
let(:distributions) { distributions }

let(:duplicate_item) do
Expand Down Expand Up @@ -51,9 +51,12 @@
let(:item_id) { distributions.flatten.first.line_items.first.item_id }
let(:filters) { {by_item_id: item_id} }
let(:item_name) { Item.find(item_id).name }
let(:organization) { distributions.first.organization }

let(:all_org_items) { Item.where(organization:).uniq.sort_by(&:created_at) }

let(:total_item_quantities) do
template = item_names.index_with(0)
template = all_org_items.pluck(:name).index_with(0)

items_lists.map do |items_list|
row = template.dup
Expand All @@ -64,7 +67,7 @@
end
end

let(:expected_headers) do
let(:non_item_headers) do
[
"Partner",
"Date of Distribution",
Expand All @@ -76,14 +79,10 @@
"State",
"Agency Representative",
"Comments"
] + expected_item_headers
]
end

let(:expected_item_headers) do
expect(item_names).not_to be_empty

item_names
end
let(:expected_headers) { non_item_headers + all_org_items.pluck(:name) }

it 'should match the expected content for the csv' do
expect(subject[0]).to eq(expected_headers)
Expand All @@ -107,5 +106,52 @@
expect(subject[idx + 1]).to eq(row)
end
end

context 'when a new item is added' do
let!(:original_columns_count) { organization.items.size + non_item_headers.size }
let(:new_item_name) { "new item" }
before do
create(:item, name: new_item_name, organization:)
end

it 'should add it to the end of the row' do
expect(subject[0]).to eq(expected_headers)
.and end_with(new_item_name)
.and have_attributes(size: original_columns_count + 1)
end

it 'should show up with a 0 quantity if there are none of this item in any distribution' do
distributions.zip(total_item_quantities).each_with_index do |(distribution, total_item_quantity), idx|
row = [
distribution.partner.name,
distribution.issued_at.strftime("%m/%d/%Y"),
distribution.storage_location.name,
distribution.line_items.where(item_id: item_id).total,
distribution.cents_to_dollar(distribution.line_items.total_value),
distribution.delivery_method,
"$#{distribution.shipping_cost.to_f}",
distribution.state,
distribution.agency_rep,
distribution.comment
]

row += total_item_quantity

expect(subject[idx + 1]).to eq(row)
.and end_with(0)
.and have_attributes(size: original_columns_count + 1)
end
end
end

context 'when there are no distributions but the report is requested' do
subject { described_class.new(distributions: [], organization: Organization.first, filters: filters).generate_csv_data }
it 'returns a csv with only headers and no rows' do
header_row = subject[0]
expect(header_row).to eq(expected_headers)
expect(header_row.last).to eq(all_org_items.last.name)
expect(subject.size).to eq(1)
end
end
end
end

0 comments on commit 404dff3

Please sign in to comment.