diff --git a/app/views/events/_event_row.html.erb b/app/views/events/_event_row.html.erb index 3ef1e11386..c10bbd37fa 100644 --- a/app/views/events/_event_row.html.erb +++ b/app/views/events/_event_row.html.erb @@ -1,8 +1,15 @@ <% if event.is_a?(SnapshotEvent) %> <%= render partial: "snapshot_event_row", object: event, as: :event, locals: { items: items, storage_locs: storage_locs } %> <% else %> - <% from_loc = event.data.items.first&.from_storage_location %> - <% to_loc = event.data.items.first&.to_storage_location %> + <% + # KitAllocateEvent/KitDeallocateEvent mix directions within a single event: the + # kit's own line item (always last) moves opposite the component items, so the + # row's From/To direction must be derived from the kit line item, not the first one. + is_kit_event = event.is_a?(KitAllocateEvent) || event.is_a?(KitDeallocateEvent) + direction_item = is_kit_event ? event.data.items.last : event.data.items.first + %> + <% from_loc = direction_item&.from_storage_location %> + <% to_loc = direction_item&.to_storage_location %> <%= event.user&.name || "No Name Provided" %> @@ -34,12 +41,12 @@ end %> <% sorted_entries.each do |entry| %> <% item = items.find { |i| i.id == entry.item_id } %> + <% quantity = entry.from_storage_location == from_loc ? entry.quantity : -entry.quantity %> <% if item %> - <%= link_to item.name, item_path(item.id) %>: + <%= link_to item.name, item_path(item.id) %>: <%= quantity %>
<% else %> - Item <%= entry.item_id %> (deleted) + Item <%= entry.item_id %> (deleted): <%= quantity %>
<% end %> - <%= entry.from_storage_location == from_loc ? entry.quantity : -entry.quantity %>
<% end %> diff --git a/spec/requests/events_requests_spec.rb b/spec/requests/events_requests_spec.rb index 0125fb03f3..0185b47cce 100644 --- a/spec/requests/events_requests_spec.rb +++ b/spec/requests/events_requests_spec.rb @@ -263,6 +263,51 @@ expect(response.body).not_to include("99
") end end + + context "with kit allocation and deallocation events" do + let(:component_item) { create(:item, organization: organization, name: "Widget") } + let(:kit) do + create_kit(organization: organization, line_items_attributes: [ + {item_id: component_item.id, quantity: 5} + ]) + end + + def row_for(event_type) + Nokogiri::HTML(response.body).css("tbody tr").find do |row| + row.css("td")[1]&.text&.strip == event_type + end + end + + before do + TestInventory.create_inventory(organization, { + storage_location.id => {component_item.id => 100} + }) + KitAllocateEvent.publish(kit, storage_location.id, 3) + KitDeallocateEvent.publish(kit, storage_location.id, 1) + end + + it "shows a positive kit quantity to the storage location and a negative item quantity for KitAllocate" do + subject + row = row_for("KitAllocate") + expect(row).not_to be_nil + cells = row.css("td") + expect(cells[4].text).not_to include(storage_location.name) + expect(cells[5].text).to include(storage_location.name) + expect(cells[6].text).to include("#{kit.name}: 3") + expect(cells[6].text).to include("Widget: -15") + end + + it "shows a positive kit quantity from the storage location and a negative item quantity for KitDeallocate" do + subject + row = row_for("KitDeallocate") + expect(row).not_to be_nil + cells = row.css("td") + expect(cells[4].text).to include(storage_location.name) + expect(cells[5].text).not_to include(storage_location.name) + expect(cells[6].text).to include("#{kit.name}: 1") + expect(cells[6].text).to include("Widget: -5") + end + end end end end