From 5217bcebedc3141a5288a97a88dcd4ab07a6e7ad Mon Sep 17 00:00:00 2001 From: guswhitten <90280763+guswhitten@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:12:56 -0400 Subject: [PATCH] Resolves #4544. filter manufacturer donations summary report by date (#4558) * Resolves #4544. filter manufacturer donations summary report by selected range * initiate workflow? * add instance variable to each manufacturer to hold number of donations in current timeframe * set donation count variable and sort using active record query * add back def volume method in manufacturer model --- app/controllers/reports_controller.rb | 4 +- app/models/manufacturer.rb | 11 ++-- app/views/reports/_manufacturer.html.erb | 10 ++-- .../manufacturer_donations_summary_spec.rb | 50 ++++++++++++++++++- 4 files changed, 62 insertions(+), 13 deletions(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 7c177789f9..cbd87cb409 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -8,9 +8,7 @@ def donations_summary def manufacturer_donations_summary @recent_donations_from_manufacturers = current_organization.donations.during(helpers.selected_range).by_source(:manufacturer) - @top_manufacturers = current_organization.manufacturers.by_donation_count - @donations = current_organization.donations.during(helpers.selected_range) - @recent_donations = @donations.recent + @top_manufacturers = current_organization.manufacturers.by_donation_count(10, helpers.selected_range) end def purchases_summary diff --git a/app/models/manufacturer.rb b/app/models/manufacturer.rb index 3a274fefa8..21034cc1eb 100644 --- a/app/models/manufacturer.rb +++ b/app/models/manufacturer.rb @@ -26,10 +26,15 @@ def volume donations.joins(:line_items).sum(:quantity) end - def self.by_donation_count(count = 10) - # selects manufacturers that have donation qty > 0 + def self.by_donation_count(count = 10, date_range = nil) + # selects manufacturers that have donation qty > 0 in the provided date range # and sorts them by highest volume of donation - select { |m| m.volume.positive? }.sort.reverse.first(count) + joins(donations: :line_items).where(donations: { issued_at: date_range }) + .select('manufacturers.*, sum(line_items.quantity) as donation_count') + .group('manufacturers.id') + .having('sum(line_items.quantity) > 0') + .order('donation_count DESC') + .limit(count) end private diff --git a/app/views/reports/_manufacturer.html.erb b/app/views/reports/_manufacturer.html.erb index 67fe3ad341..ea42675571 100644 --- a/app/views/reports/_manufacturer.html.erb +++ b/app/views/reports/_manufacturer.html.erb @@ -1,5 +1,5 @@ -
- <%= link_to manufacturer do %> - <%= manufacturer.name %> (<%= number_with_delimiter(manufacturer.volume) %>) - <% end %> -
+
+ <%= link_to manufacturer do %> + <%= manufacturer.name %> (<%= number_with_delimiter(manufacturer.donation_count) %>) + <% end %> +
diff --git a/spec/requests/reports/manufacturer_donations_summary_spec.rb b/spec/requests/reports/manufacturer_donations_summary_spec.rb index bd3285c751..e9172e1e9e 100644 --- a/spec/requests/reports/manufacturer_donations_summary_spec.rb +++ b/spec/requests/reports/manufacturer_donations_summary_spec.rb @@ -1,6 +1,9 @@ RSpec.describe "Reports::ManufacturerDonationsSummary", type: :request do let(:organization) { create(:organization) } let(:user) { create(:user, organization: organization) } + let(:manufacturer1) { create(:manufacturer, organization: organization, name: "Manufacturer 1") } + let(:manufacturer2) { create(:manufacturer, organization: organization, name: "Manufacturer 2") } + let(:manufacturer3) { create(:manufacturer, organization: organization, name: "Manufacturer 3") } describe "while signed in" do before do @@ -9,13 +12,56 @@ describe "GET #index" do subject do - get reports_manufacturer_donations_summary_path(format: response_format) + get reports_manufacturer_donations_summary_path(format: "html") response end - let(:response_format) { "html" } it { is_expected.to have_http_status(:success) } end + + context "when visiting the summary page" do + it "has a link to create a new donation" do + get reports_manufacturer_donations_summary_path + + expect(response.body).to include("New Donation") + expect(response.body).to include("#{@url_prefix}/donations/new") + end + + context "with manufacturer donations in the last year" do + let(:formatted_date_range) { date_range.map { _1.to_formatted_s(:date_picker) }.join(" - ") } + let(:date_range) { [1.year.ago, 0.days.ago] } + let!(:donations) do + [ + create(:donation, :with_items, item_quantity: 2, issued_at: 5.days.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer1), + create(:donation, :with_items, item_quantity: 3, issued_at: 3.months.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer1), + create(:donation, :with_items, item_quantity: 7, issued_at: 2.years.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer2), + create(:donation, :with_items, item_quantity: 1, issued_at: 0.days.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer2), + create(:donation, :with_items, item_quantity: 13, issued_at: 20.days.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer3), + create(:donation, :with_items, item_quantity: 17, issued_at: 5.years.ago, organization: organization, source: "Manufacturer", manufacturer: manufacturer3) + ] + end + + it "shows correct total received donations" do + get reports_manufacturer_donations_summary_path(user.organization), params: {filters: {date_range: formatted_date_range}} + + expect(response.body).to match(%r{\s*19\s*}) + end + + it "shows correct individual donations for each manufacturer" do + get reports_manufacturer_donations_summary_path(user.organization), params: {filters: {date_range: formatted_date_range}} + + expect(response.body).to match(%r{Manufacturer 1 \(5\)}) + expect(response.body).to match(%r{Manufacturer 2 \(1\)}) + expect(response.body).to match(%r{Manufacturer 3 \(13\)}) + end + + it "shows top manufacturers in desc. order" do + get reports_manufacturer_donations_summary_path(user.organization), params: {filters: {date_range: formatted_date_range}} + + expect(response.body).to match(%r{Manufacturer 3 .* Manufacturer 1 .*Manufacturer 2}m) + end + end + end end describe "while not signed in" do