From 38adc4502f9726c7bebf8bb6af94853e8dd4d188 Mon Sep 17 00:00:00 2001 From: Daniel Orner Date: Sun, 16 Jun 2024 10:13:39 -0400 Subject: [PATCH 1/2] Show inventory history for pre-event read --- .../storage_locations_controller.rb | 10 ++- app/models/view/inventory.rb | 25 ++++++ app/views/storage_locations/show.html.erb | 7 ++ lib/tasks/kill_postgres_connections.rake | 3 +- spec/models/item_unit_spec.rb | 2 +- .../storage_locations_requests_spec.rb | 81 ++++++++++++++++--- 6 files changed, 113 insertions(+), 15 deletions(-) diff --git a/app/controllers/storage_locations_controller.rb b/app/controllers/storage_locations_controller.rb index d2a622c42b..91961d696a 100644 --- a/app/controllers/storage_locations_controller.rb +++ b/app/controllers/storage_locations_controller.rb @@ -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| diff --git a/app/models/view/inventory.rb b/app/models/view/inventory.rb index ea291eae09..08a209fe7e 100644 --- a/app/models/view/inventory.rb +++ b/app/models/view/inventory.rb @@ -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] + 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) diff --git a/app/views/storage_locations/show.html.erb b/app/views/storage_locations/show.html.erb index caa56c27bf..530410fa34 100644 --- a/app/views/storage_locations/show.html.erb +++ b/app/views/storage_locations/show.html.erb @@ -102,6 +102,13 @@ <%= number_with_delimiter(item.quantity) %> <% end %> + <% elsif @legacy_inventory %> + <% @legacy_inventory.each do |item| %> + + <%= link_to item.name, item_path(item.item_id) %> + <%= number_with_delimiter(item.quantity) %> + + <% end %> <% else %> <%= render partial: "inventory_item_row", collection: @storage_location.inventory_items.joins(:item).where(items: { active: true }), diff --git a/lib/tasks/kill_postgres_connections.rake b/lib/tasks/kill_postgres_connections.rake index 3004dd8545..6cba38d3a9 100644 --- a/lib/tasks/kill_postgres_connections.rake +++ b/lib/tasks/kill_postgres_connections.rake @@ -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 = < :kill_postgres_connections \ No newline at end of file +task "db:drop" => :kill_postgres_connections diff --git a/spec/models/item_unit_spec.rb b/spec/models/item_unit_spec.rb index 70ebd9cc06..be63d21e09 100644 --- a/spec/models/item_unit_spec.rb +++ b/spec/models/item_unit_spec.rb @@ -1,6 +1,6 @@ # == Schema Information # -# Table name: item_request_units +# Table name: item_units # # id :bigint not null, primary key # name :string not null diff --git a/spec/requests/storage_locations_requests_spec.rb b/spec/requests/storage_locations_requests_spec.rb index fbde891162..b228d15376 100644 --- a/spec/requests/storage_locations_requests_spec.rb +++ b/spec/requests/storage_locations_requests_spec.rb @@ -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 From d54f0cc7cd88f46d4607a5faf01e4ea2edb1e4f4 Mon Sep 17 00:00:00 2001 From: Daniel Orner Date: Sun, 23 Jun 2024 10:02:26 -0400 Subject: [PATCH 2/2] Fix totals --- app/views/storage_locations/show.html.erb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/storage_locations/show.html.erb b/app/views/storage_locations/show.html.erb index 530410fa34..4baf8b3d35 100644 --- a/app/views/storage_locations/show.html.erb +++ b/app/views/storage_locations/show.html.erb @@ -118,7 +118,15 @@ Total - <%= @inventory ? @inventory.quantity_for(storage_location: @storage_location.id) : @storage_location.size %> + + <% 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 %> +