From 1632459b0f6ddfd684de2462ed431c159daa6447 Mon Sep 17 00:00:00 2001 From: Rodrigo Virgilio Date: Mon, 6 Jul 2026 16:01:45 +0100 Subject: [PATCH 1/2] Fix kit allocation/deallocation history display direction (fixes #5568) --- app/views/events/_event_row.html.erb | 11 +++++-- spec/requests/events_requests_spec.rb | 45 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/views/events/_event_row.html.erb b/app/views/events/_event_row.html.erb index 3ef1e11386..6936a17513 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" %> 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 From 750e14ab85a543103edbdaecedcd1462bf114aa5 Mon Sep 17 00:00:00 2001 From: Rodrigo Virgilio Date: Mon, 6 Jul 2026 22:42:05 +0100 Subject: [PATCH 2/2] Fix whitespace in event row item/quantity text (fixes #5568) --- app/views/events/_event_row.html.erb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/events/_event_row.html.erb b/app/views/events/_event_row.html.erb index 6936a17513..c10bbd37fa 100644 --- a/app/views/events/_event_row.html.erb +++ b/app/views/events/_event_row.html.erb @@ -41,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 %>