From f0ea16f5a6255ebb1db85f7f3079fa698e1366c3 Mon Sep 17 00:00:00 2001 From: Mike Virata-Stone Date: Sat, 17 Jan 2026 11:04:00 -0800 Subject: [PATCH] Easy way to fix county for closed donations --- app/controllers/donations_controller.rb | 15 ++++- app/helpers/donations_helper.rb | 13 ++++ app/models/donation.rb | 9 +++ app/views/donations/_table.html.erb | 10 +++- config/routes.rb | 1 + spec/controllers/dontions_controller_spec.rb | 4 -- spec/requests/donations_request_spec.rb | 63 ++++++++++++++++++++ 7 files changed, 109 insertions(+), 6 deletions(-) delete mode 100644 spec/controllers/dontions_controller_spec.rb create mode 100644 spec/requests/donations_request_spec.rb diff --git a/app/controllers/donations_controller.rb b/app/controllers/donations_controller.rb index f9dc0a39..88f3963c 100644 --- a/app/controllers/donations_controller.rb +++ b/app/controllers/donations_controller.rb @@ -2,7 +2,7 @@ class DonationsController < ApplicationController require_permission :can_sync_donations?, only: %i[sync] require_permission :can_view_donations? require_permission :can_create_donations?, except: %i[index show] - require_permission :can_close_donations?, only: %i[close closed] + require_permission :can_close_donations?, only: %i[close closed fix_county] require_permission :can_delete_and_restore_donations?, only: %i[deleted destroy restore] require_permission :can_delete_closed_donations?, only: %i[destroy_closed] before_action :authenticate_user! @@ -106,6 +106,19 @@ def restore end end + def fix_county + donation = Donation.find(params[:id]) + + if donation.county_id.present? + redirect_to closed_donations_path, flash: { error: "Donation already has a county!" } + elsif donation.donor.county_id.blank? + redirect_to closed_donations_path, flash: { error: "Donor doesn't have a county!" } + else + donation.fix_county! + redirect_to closed_donations_path, flash: { success: "Donation county fixed." } + end + end + def sync donation = current_user.sync_donation(params) redirect_to donation_path(donation) diff --git a/app/helpers/donations_helper.rb b/app/helpers/donations_helper.rb index 0aa9f230..7e8cfe4a 100644 --- a/app/helpers/donations_helper.rb +++ b/app/helpers/donations_helper.rb @@ -1,4 +1,17 @@ module DonationsHelper + def fix_donation_county_button(donation) + css_class = "btn btn-danger" + css_class += " disabled" if donation.donor.county_id.blank? + + button = button_to "Fix", fix_county_donation_path(donation), class: css_class, method: :post, disabled: donation.donor.county_id.blank? + + if donation.donor.county_id.blank? + disabled_title_wrapper("Please update the donor with a county.") { button } + else + button + end + end + def sync_donation_button(donation) css_class = "btn btn-primary" diff --git a/app/models/donation.rb b/app/models/donation.rb index 92802537..34e9d399 100644 --- a/app/models/donation.rb +++ b/app/models/donation.rb @@ -177,6 +177,15 @@ def add_to_donation!(params, required: false) end end + def fix_county! + raise "County is already present!" if county_id.present? + + @allow_change_after_closed = true + update!(county_id: donor.county_id) + ensure + @allow_change_after_closed = false + end + private def skip_adding_donations?(params, required) diff --git a/app/views/donations/_table.html.erb b/app/views/donations/_table.html.erb index fe76b18c..3f834f73 100644 --- a/app/views/donations/_table.html.erb +++ b/app/views/donations/_table.html.erb @@ -26,7 +26,15 @@ <% @donations.each do |donation| %> > <%= donation.id %> - <%= donation.county&.name %> + + + <%= donation.county&.name %> + + <% if donation.county.blank? && local_assigns[:for_closed] %> + <%= fix_donation_county_button(donation) %> + <% end %> + + <%= truncate donation.donor.name, length: 50 %> <%= donation.item_count %> <%= number_to_currency(donation.value, unit: "$", precision: 2) %> diff --git a/config/routes.rb b/config/routes.rb index d76ea08b..641b139b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,7 @@ member do post :close + post :fix_county patch :restore post :sync delete :destroy_closed diff --git a/spec/controllers/dontions_controller_spec.rb b/spec/controllers/dontions_controller_spec.rb deleted file mode 100644 index debb2690..00000000 --- a/spec/controllers/dontions_controller_spec.rb +++ /dev/null @@ -1,4 +0,0 @@ -require "rails_helper" - -describe DonationsController, type: :controller do -end diff --git a/spec/requests/donations_request_spec.rb b/spec/requests/donations_request_spec.rb new file mode 100644 index 00000000..a4fe8e19 --- /dev/null +++ b/spec/requests/donations_request_spec.rb @@ -0,0 +1,63 @@ +require "rails_helper" + +RSpec.describe DonationsController, type: :request do + let!(:user) { users(:root) } + + before do + sign_in user + end + + describe "#fix_county" do + context "when the donation already has a county (even though different from donor)" do + let(:donation) { donations(:donation_with_donor_with_different_county) } + + before do + donation.update_column(:closed_at, Time.zone.now) + end + + it "throws an error" do + expect(donation.county).not_to eq(donation.donor.county) + post "/donations/#{donation.id}/fix_county" + expect(flash[:error]).to be_present + + donation.reload + expect(donation.county).not_to eq(donation.donor.county) + end + end + + context "when the donation doesn't have a county but the donor does" do + let(:donation) { donations(:donation_with_donor_with_county) } + + before do + donation.update_column(:closed_at, Time.zone.now) + end + + it "updates the county" do + expect(donation.county).to be_blank + post "/donations/#{donation.id}/fix_county" + expect(flash[:error]).to be_blank + + donation.reload + expect(donation.county).to eq(donation.donor.county) + end + end + + context "when the donation doesn't have a county but neither does the donor" do + let(:donation) { donations(:trois_donation) } + + before do + donation.update_column(:closed_at, Time.zone.now) + end + + it "throws an error" do + expect(donation.county).to be_blank + expect(donation.donor.county).to be_blank + post "/donations/#{donation.id}/fix_county" + expect(flash[:error]).to be_present + + donation.reload + expect(donation.county).to be_blank + end + end + end +end