Skip to content

Commit cf5c061

Browse files
authored
Fix the issue where only one error is displayed, even when multiple errors are present. (#4911)
* Fix the issue where only one error is displayed, even when multiple errors are present. * Fix the numbers in brackets are disappear after a failed submission. * Rename load_items_controller.js to trigger_change_event_controller.js
1 parent 2bf2e73 commit cf5c061

File tree

8 files changed

+73
-24
lines changed

8 files changed

+73
-24
lines changed

app/events/event_types/event_storage_location.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def reduce_inventory(item_id, quantity, validate: true)
3232
if validate
3333
current_quantity = items[item_id]&.quantity || 0
3434
if current_quantity < quantity
35-
raise InventoryError.new("Could not reduce quantity by #{quantity} - current quantity is #{current_quantity}",
35+
raise InventoryActionError.new("Could not reduce quantity by #{quantity} - current quantity is #{current_quantity}",
3636
item_id,
3737
id)
3838
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class InventoryActionError < StandardError
2+
# @return [Integer]
3+
attr_accessor :item_id
4+
# @return [Integer]
5+
attr_accessor :storage_location_id
6+
7+
# @param message [String]
8+
# @param item_id [Integer]
9+
# @param storage_location_id [Integer]
10+
def initialize(message, item_id, storage_location_id)
11+
super(message)
12+
self.item_id = item_id
13+
self.storage_location_id = storage_location_id
14+
end
15+
end

app/events/inventory_aggregate.rb

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,29 +66,36 @@ def handle(event, inventory, validate: false, previous_event: nil)
6666
# @param validate [Boolean]
6767
# @param previous_event [Event]
6868
def handle_inventory_event(payload, inventory, validate: true, previous_event: nil)
69+
errors = []
6970
payload.items.each do |line_item|
7071
quantity = line_item.quantity
7172
if previous_event
7273
previous_item = previous_event.data.items.find { |i| i.same_item?(line_item) }
7374
quantity -= previous_item.quantity if previous_item
7475
end
75-
inventory.move_item(item_id: line_item.item_id,
76+
move_item(inventory: inventory,
77+
item_id: line_item.item_id,
7678
quantity: quantity,
7779
from_location: line_item.from_storage_location,
7880
to_location: line_item.to_storage_location,
79-
validate: validate)
81+
validate: validate,
82+
errors: errors)
8083
end
8184
# remove the quantity from any items that are now missing
8285
previous_event&.data&.items&.each do |previous_item|
8386
new_item = payload.items.find { |i| i.same_item?(previous_item) }
8487
if new_item.nil?
85-
inventory.move_item(item_id: previous_item.item_id,
88+
move_item(inventory: inventory,
89+
item_id: previous_item.item_id,
8690
quantity: previous_item.quantity,
8791
from_location: previous_item.to_storage_location,
8892
to_location: previous_item.from_storage_location,
89-
validate: validate)
93+
validate: validate,
94+
errors: errors)
9095
end
9196
end
97+
98+
raise InventoryError.new(errors.map(&:message).join("\n")) unless errors.empty?
9299
end
93100

94101
# @param payload [EventTypes::InventoryPayload]
@@ -100,6 +107,19 @@ def handle_audit_event(payload, inventory)
100107
location: line_item.to_storage_location)
101108
end
102109
end
110+
111+
def move_item(inventory:, item_id:, quantity:, from_location:, to_location:, validate:, errors:)
112+
inventory.move_item(item_id: item_id,
113+
quantity: quantity,
114+
from_location: from_location,
115+
to_location: to_location,
116+
validate: validate)
117+
rescue InventoryActionError => e
118+
item = Item.find_by(id: e.item_id)&.name || "Item ID #{e.item_id}"
119+
loc = StorageLocation.find_by(id: e.storage_location_id)&.name || "Storage Location ID #{e.storage_location_id}"
120+
e.message << " for #{item} in #{loc}"
121+
errors.push(e)
122+
end
103123
end
104124

105125
# ignore previous events

app/events/inventory_error.rb

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
11
class InventoryError < StandardError
22
# @return [Event]
33
attr_accessor :event
4-
# @return [Integer]
5-
attr_accessor :item_id
6-
# @return [Integer]
7-
attr_accessor :storage_location_id
8-
9-
# @param message [String]
10-
# @param item_id [Integer]
11-
# @param storage_location_id [Integer]
12-
def initialize(message, item_id, storage_location_id)
13-
super(message)
14-
self.item_id = item_id
15-
self.storage_location_id = storage_location_id
16-
end
174
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Controller} from "@hotwired/stimulus"
2+
3+
export default class extends Controller {
4+
connect() {
5+
this.triggerChangeEvent();
6+
}
7+
8+
triggerChangeEvent() {
9+
if (this.element.value) {
10+
const event = new Event("change", {bubbles: true});
11+
this.element.dispatchEvent(event);
12+
}
13+
}
14+
}

app/models/event.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ def self.most_recent_snapshot(organization_id)
7777
def validate_inventory
7878
InventoryAggregate.inventory_for(organization_id, validate: true)
7979
rescue InventoryError => e
80-
item = Item.find_by(id: e.item_id)&.name || "Item ID #{e.item_id}"
81-
loc = StorageLocation.find_by(id: e.storage_location_id)&.name || "Storage Location ID #{e.storage_location_id}"
82-
e.message << " for #{item} in #{loc}"
8380
if e.event != self
8481
e.message.prepend("Error occurred when re-running events: #{e.event.type} on #{e.event.created_at.to_date}: ")
8582
e.message << " Please contact the Human Essentials admin staff for assistance."

app/views/storage_locations/_source.html.erb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
format: :json
2020
)
2121
},
22-
class: "storage-location-source"
22+
class: "storage-location-source",
23+
"data-controller": "trigger-change-event"
2324
} %>

spec/events/inventory_aggregate_spec.rb

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,20 +720,35 @@
720720
end
721721

722722
describe "validation" do
723+
let(:donation) { FactoryBot.create(:donation, organization: organization, storage_location: storage_location1) }
724+
let(:distribution) { FactoryBot.create(:distribution, organization: organization, storage_location: storage_location1) }
723725
context "current event is incorrect" do
724726
it "should raise a bare error" do
725-
donation = FactoryBot.create(:donation, organization: organization, storage_location: storage_location1)
726727
donation.line_items << build(:line_item, quantity: 50, item: item1)
727728
DonationEvent.publish(donation)
728729

729-
distribution = FactoryBot.create(:distribution, organization: organization, storage_location: storage_location1)
730730
distribution.line_items << build(:line_item, quantity: 100, item: item1, itemizable: distribution)
731731
expect { DistributionEvent.publish(distribution) }.to raise_error do |e|
732732
expect(e).to be_a(InventoryError)
733733
expect(e.event).to be_a(DistributionEvent)
734734
expect(e.message).to eq("Could not reduce quantity by 100 - current quantity is 50 for #{item1.name} in #{storage_location1.name}")
735735
end
736736
end
737+
738+
context "while there are multiple errors" do
739+
it "should show all the errors" do
740+
donation.line_items << build(:line_item, quantity: 50, item: item1) << build(:line_item, quantity: 50, item: item2)
741+
DonationEvent.publish(donation)
742+
743+
distribution.line_items << build(:line_item, quantity: 100, item: item1) << build(:line_item, quantity: 100, item: item2)
744+
expect { DistributionEvent.publish(distribution) }.to raise_error do |e|
745+
expect(e).to be_a(InventoryError)
746+
expect(e.event).to be_a(DistributionEvent)
747+
expect(e.message).to eq("Could not reduce quantity by 100 - current quantity is 50 for #{item1.name} in #{storage_location1.name}\n" \
748+
"Could not reduce quantity by 100 - current quantity is 50 for #{item2.name} in #{storage_location1.name}")
749+
end
750+
end
751+
end
737752
end
738753

739754
context "subsequent event is incorrect" do

0 commit comments

Comments
 (0)