Skip to content

Commit

Permalink
Merge pull request #4469 from rubyforgood/4433-inventory-history
Browse files Browse the repository at this point in the history
Show inventory history for pre-event read
  • Loading branch information
awwaiid committed Jul 7, 2024
2 parents 846dd95 + d54f0cc commit 89b56e4
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 15 deletions.
10 changes: 9 additions & 1 deletion app/controllers/storage_locations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,15 @@ def show
@items_in = ItemsInQuery.new(organization: current_organization, storage_location: @storage_location).call
@items_in_total = ItemsInTotalQuery.new(organization: current_organization, storage_location: @storage_location).call
if Event.read_events?(current_organization)
@inventory = View::Inventory.new(current_organization.id, event_time: params[:version_date])
if View::Inventory.within_snapshot?(current_organization.id, params[:version_date])
@inventory = View::Inventory.new(current_organization.id, event_time: params[:version_date])
else
@legacy_inventory = View::Inventory.legacy_inventory_for_storage_location(
current_organization.id,
@storage_location.id,
params[:version_date]
)
end
end

respond_to do |format|
Expand Down
25 changes: 25 additions & 0 deletions app/models/view/inventory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,31 @@ class ViewInventoryItem < EventTypes::EventItem
attr_accessor :inventory, :organization_id
delegate :storage_locations, to: :inventory

# @param event_time [ActiveSupport::TimeWithZone]
# @return [Boolean]
def self.within_snapshot?(organization_id, event_time)
return true if event_time.blank?

event = SnapshotEvent.where(organization_id: organization_id).first
event && event.created_at < event_time
end

# @param organization_id [Integer]
# @param storage_location_id [Integer]
# @param event_time [ActiveSupport::TimeWithZone]
# @return [Array<ViewInventoryItem>]
def self.legacy_inventory_for_storage_location(organization_id, storage_location_id, event_time)
items = Organization.find(organization_id).inventory_items.where(storage_location_id: storage_location_id)
items.map do |item|
ViewInventoryItem.new(
item_id: item.item_id,
quantity: item.paper_trail.version_at(event_time)&.quantity || 0,
storage_location_id: storage_location_id,
db_item: item.item
)
end
end

# @param organization_id [Integer]
# @param event_time [DateTime]
def initialize(organization_id, event_time: nil)
Expand Down
17 changes: 16 additions & 1 deletion app/views/storage_locations/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@
<td><%= number_with_delimiter(item.quantity) %></td>
</tr>
<% end %>
<% elsif @legacy_inventory %>
<% @legacy_inventory.each do |item| %>
<tr>
<td><%= link_to item.name, item_path(item.item_id) %></td>
<td><%= number_with_delimiter(item.quantity) %></td>
</tr>
<% end %>
<% else %>
<%= render partial: "inventory_item_row",
collection: @storage_location.inventory_items.joins(:item).where(items: { active: true }),
Expand All @@ -111,7 +118,15 @@
<tfoot>
<tr>
<td>Total</td>
<td><%= @inventory ? @inventory.quantity_for(storage_location: @storage_location.id) : @storage_location.size %></td>
<td>
<% if @inventory %>
<%= number_with_delimiter(@inventory.quantity_for(storage_location: @storage_location.id)) %>
<% elsif @legacy_inventory %>
<%= number_with_delimiter(@legacy_inventory.map(&:quantity).sum) %>
<% else %>
<%= number_with_delimiter(@storage_location.size) %>
<% end %>
</td>
</tr>
</tfoot>
</table>
Expand Down
3 changes: 2 additions & 1 deletion lib/tasks/kill_postgres_connections.rake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
task :kill_postgres_connections => :environment do
puts "Killing existing Postgres connections - you may be prompted for your computer admin password"
db_name = Rails.configuration.database_configuration[Rails.env]['database']
sh = <<EOF
ps xa \
Expand All @@ -12,4 +13,4 @@ EOF
puts "Done killing the connections!"
end

task "db:drop" => :kill_postgres_connections
task "db:drop" => :kill_postgres_connections
81 changes: 69 additions & 12 deletions spec/requests/storage_locations_requests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,77 @@
let(:inventory_item) { storage_location.inventory_items.first }

context "with a version found" do
it "should show the version specified" do
travel 1.day do
inventory_item.update!(quantity: 100)
context "with events_read on" do
before(:each) { allow(Event).to receive(:read_events?).and_return(true) }
context "before active events" do
it "should show the version specified" do
travel 1.day do
inventory_item.update!(quantity: 100)
end
travel 1.week do
inventory_item.update!(quantity: 300)
end
travel 8.days do
SnapshotEvent.delete_all
SnapshotEvent.publish(organization)
end
travel 2.weeks do
get storage_location_path(storage_location, format: response_format,
version_date: 9.days.ago.to_date.to_fs(:db))
expect(response).to be_successful
expect(response.body).to include("Smithsonian")
expect(response.body).to include("Test Item")
expect(response.body).to include("100")
end
end
end
travel 1.week do
inventory_item.update!(quantity: 300)

context "with active events" do
it 'should show the right version' do
travel 1.day do
TestInventory.create_inventory(organization, {
storage_location.id => {
item.id => 100,
item2.id => 0
}
})
end
travel 1.week do
TestInventory.create_inventory(organization, {
storage_location.id => {
item.id => 300,
item2.id => 0
}
})
end
travel 2.weeks do
get storage_location_path(storage_location, format: response_format,
version_date: 9.days.ago.to_date.to_fs(:db))
expect(response).to be_successful
expect(response.body).to include("Smithsonian")
expect(response.body).to include("Test Item")
expect(response.body).to include("100")
end
end
end
travel 2.weeks do
get storage_location_path(storage_location, format: response_format,
version_date: 9.days.ago.to_date.to_fs(:db))
expect(response).to be_successful
expect(response.body).to include("Smithsonian")
expect(response.body).to include("Test Item")
expect(response.body).to include("100")
end
context "with events_read off" do
before(:each) { allow(Event).to receive(:read_events?).and_return(false) }
it "should show the version specified" do
travel 1.day do
inventory_item.update!(quantity: 100)
end
travel 1.week do
inventory_item.update!(quantity: 300)
end
travel 2.weeks do
get storage_location_path(storage_location, format: response_format,
version_date: 9.days.ago.to_date.to_fs(:db))
expect(response).to be_successful
expect(response.body).to include("Smithsonian")
expect(response.body).to include("Test Item")
expect(response.body).to include("100")
end
end
end
end
Expand Down

0 comments on commit 89b56e4

Please sign in to comment.