diff --git a/app/views/donations/edit.html.erb b/app/views/donations/edit.html.erb
index b7718e256a..6abc0d8eb9 100644
--- a/app/views/donations/edit.html.erb
+++ b/app/views/donations/edit.html.erb
@@ -2,10 +2,10 @@
- <% content_for :title, "Edit - Donations - #{@donation.source} - #{current_organization.name}" %>
+ <% content_for :title, "Edit - Donations - #{@original_source ? @original_source : @donation.source} - #{current_organization.name}" %>
Editing Donation
- from <%= @donation.source %>
+ from <%= @original_source ? @original_source : @donation.source %>
@@ -39,7 +39,7 @@
- <%= render partial: "donation_form", object: @donation %>
+ <%= render partial: "donation_form", object: @previous_input ? @previous_input : @donation %>
<%= link_to "Add vendor", new_vendor_path, {:remote => true, "data-bs-toggle" => "modal", "data-bs-target" => "#modal-window", id: "new_vendor", "style" => "display: none;"} %>
diff --git a/spec/controllers/donations_controller_spec.rb b/spec/controllers/donations_controller_spec.rb
index 64a1c7c92f..a42080161a 100644
--- a/spec/controllers/donations_controller_spec.rb
+++ b/spec/controllers/donations_controller_spec.rb
@@ -58,7 +58,6 @@
line_item = donation.line_items.first
line_item_params = {
"0" => {
- "_destroy" => "false",
item_id: line_item.item_id,
quantity: "15",
id: line_item.id
@@ -82,7 +81,6 @@
line_item = donation.line_items.first
line_item_params = {
"0" => {
- "_destroy" => "false",
item_id: line_item.item_id,
quantity: "8",
id: line_item.id
@@ -111,7 +109,6 @@
line_item = donation.line_items.first
line_item_params = {
"0" => {
- "_destroy" => "false",
item_id: line_item.item_id,
quantity: "1",
id: line_item.id
@@ -119,7 +116,7 @@
}
donation_params = { source: donation.source, storage_location: new_storage_location, line_items_attributes: line_item_params }
put :update, params: { id: donation.id, donation: donation_params }
- expect(response).not_to redirect_to(anything)
+ expect(response).not_to redirect_to(edit_donation_path(donation))
expect(original_storage_location.size).to eq 5
expect(new_storage_location.size).to eq 0
expect(donation.reload.line_items.first.quantity).to eq 10
@@ -127,24 +124,19 @@
end
describe "when removing a line item" do
- it "updates storage invetory item quantity correctly" do
- donation = create(:donation, :with_items, item_quantity: 10)
- line_item = donation.line_items.first
- line_item_params = {
- "0" => {
- "_destroy" => "true",
- item_id: line_item.item_id,
- id: line_item.id
- }
- }
- donation_params = { source: donation.source, line_items_attributes: line_item_params }
+ it "updates storage inventory item quantity correctly" do
+ item_id = 1
+ item_quantity = 10
+ donation = create(:donation, :with_items, item: create(:item, id: item_id), item_quantity: item_quantity)
+ # if all line items including blanks are deleted line_items_attributes parameter is not sent
+ donation_params = { source: donation.source }
expect do
put :update, params: { id: donation.id, donation: donation_params }
- end.to change { donation.storage_location.inventory_items.first.quantity }.by(-10)
+ end.to change { donation.storage_location.inventory_items.first.quantity }.by(-1 * item_quantity)
.and change {
View::Inventory.new(donation.organization_id)
- .quantity_for(storage_location: donation.storage_location_id, item_id: line_item.item_id)
- }.by(-10)
+ .quantity_for(storage_location: donation.storage_location_id, item_id: item_id)
+ }.by(-1 * item_quantity)
end
end
end
diff --git a/spec/factories/donations.rb b/spec/factories/donations.rb
index a248c76b6e..7791bba25b 100644
--- a/spec/factories/donations.rb
+++ b/spec/factories/donations.rb
@@ -42,15 +42,15 @@
end
trait :with_items do
+ transient do
+ item_quantity { 100 }
+ item { nil }
+ end
storage_location do
create :storage_location, :with_items,
item: item || create(:item, value_in_cents: 100),
organization: organization
end
- transient do
- item_quantity { 100 }
- item { nil }
- end
after(:build) do |donation, evaluator|
event_item = View::Inventory.new(donation.organization_id)
diff --git a/spec/requests/donations_requests_spec.rb b/spec/requests/donations_requests_spec.rb
index 59e90164bf..963a5244c6 100644
--- a/spec/requests/donations_requests_spec.rb
+++ b/spec/requests/donations_requests_spec.rb
@@ -192,5 +192,83 @@
expect(response.body).to_not include("you’ll need to make an adjustment to the inventory as well.")
end
end
+
+ # Bug fix - Issue #4172
+ context "when donated items are distributed to less than donated amount " \
+ "and you edit the donation to less than distributed amount" do
+ it "shows a warning and displays original names and amounts and info the user entered" do
+ item_name = "Brightbloom Seed"
+ item = create(:item, organization: organization, name: item_name)
+ storage_location = create(:storage_location, :with_items, item: item, item_quantity: 0, organization: organization)
+ extra_item_name = "Extra Item"
+ extra_item = create(:item, organization: organization, name: extra_item_name)
+ item_to_delete_name = "Item To Delete"
+ item_to_delete = create(:item, organization: organization, name: item_to_delete_name)
+ TestInventory.create_inventory(organization, { storage_location.id => { item.id => 0, extra_item.id => 1 } })
+ original_quantity = 100
+ original_source = Donation::SOURCES[:manufacturer]
+ original_date = DateTime.new(2024)
+ donation = build(:manufacturer_donation, issued_at: original_date, organization: organization, storage_location: storage_location, source: original_source)
+ donation.line_items << build(:line_item, item: item, quantity: original_quantity)
+ donation.line_items << build(:line_item, item: item_to_delete, quantity: 1)
+
+ DonationCreateService.call(donation)
+
+ # simulate distribution by setting item inventory to 10
+ TestInventory.create_inventory(organization, { storage_location.id => { item.id => 10, extra_item.id => 1 } })
+
+ edited_source = Donation::SOURCES[:product_drive]
+ edited_source_drive_name = "Test Product Drive"
+ edited_source_drive = create(:product_drive, name: edited_source_drive_name, organization: organization)
+ edited_source_drive_participant_business_name = "Test Business Name"
+ edited_source_drive_participant = create(:product_drive_participant, business_name: edited_source_drive_participant_business_name, organization: organization)
+ edited_storage_location_name = "Test Storage"
+ edited_storage_location = create(:storage_location, name: edited_storage_location_name, organization: organization)
+ edited_money = 10.0
+ edited_comment = "New test comment"
+ edited_date = "2019-01-01"
+ extra_quantity = 1
+ edited_quantity = 1
+
+ # deleted item is removed from line_items_attributes entirely
+ edited_donation = {
+ source: edited_source,
+ product_drive_id: edited_source_drive.id,
+ product_drive_participant_id: edited_source_drive_participant.id,
+ storage_location_id: edited_storage_location.id,
+ money_raised_in_dollars: edited_money,
+ comment: edited_comment,
+ issued_at: edited_date,
+ line_items_attributes: {
+ "0": { item_id: item.id, quantity: edited_quantity },
+ "1": { item_id: extra_item.id, quantity: extra_quantity }
+ }
+ }
+
+ put donation_path(id: donation.id, donation: edited_donation)
+
+ if Event.read_events?(organization)
+ expect(flash[:alert]).to include("Error updating donation: Could not reduce quantity")
+ else # TODO remove this branch when switching to events
+ expect(flash[:alert]).to include("Error updating donation: Requested items exceed the available inventory")
+ end
+
+ expect(response.body).to include("Edit - Donations - #{original_source}")
+ expect(response.body).to include("Editing Donation\n
from #{original_source}")
+ expect(response.body).to include("\n Editing #{original_source}")
+ expect(response.body).to include("")
+ expect(response.body).to include("")
+ expect(response.body).to include("")
+ expect(response.body).to include("")
+ expect(response.body).to include(edited_comment)
+ expect(response.body).to include("value=\"#{edited_money}\" type=\"text\" name=\"donation[money_raised_in_dollars]")
+ expect(response.body).to include(edited_date)
+ expect(response.body).to include("")
+ expect(response.body).to include("value=\"#{edited_quantity}\" name=\"donation[line_items_attributes][0][quantity]")
+ expect(response.body).to include("")
+ expect(response.body).to include("value=\"#{extra_quantity}\" name=\"donation[line_items_attributes][1][quantity]")
+ expect(response.body).not_to include("")
+ end
+ end
end
end