diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a1c7e260a3..f8a23fd295 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,13 +17,21 @@ You won't be yelled at for giving your best effort. The worst that can happen is # Getting Started ## Local Environment 🛠️ + +#### Install WSL2 first if Using Windows +Follow [documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10) from Microsoft for enabling and installing Windows Subsystem For Linux 2 on your machine. + +Make sure to install **Ubuntu** as your Linux distribution. (This should be default.) + +**Note:** If you run into any issues with a command not running, restart your machine. + + 1. Install Ruby - Install the version specified in [`.ruby-version`](.ruby-version). - Visit the [Install Ruby on Rails](https://gorails.com/setup/osx/12-monterey) guide by GoRails for Ubuntu, Windows, and macOSX setup. ⚠️ Follow only the Installing Ruby step, as our project setup differs ⚠️ It is highly recommended you use a ruby version manager such as [rbenv](https://github.com/rbenv/rbenv), [asdf](https://asdf-vm.com/), or [rvm](https://rvm.io/). - Verify that your Ruby installation works by running `ruby -v`. 2. Install Postgres - Follow one of these guides: [MacOSX](https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-macos), [Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-ubuntu-18-04). - - Do you develop on Windows? We'd love to hear (and for you to submit a PR explaining) how you do it. 🙏🏻 - Create a `database.yml` file on `config/` directory with your database configurations. You can also copy the existing files called [`database.yml.example`](config/database.yml.example) and [`.env.example`](.env.example) and change the credentials. 3. Clone the project and switch to its directory 4. Run `bin/setup` diff --git a/Gemfile b/Gemfile index 8bc1e4f459..d3d0473d11 100644 --- a/Gemfile +++ b/Gemfile @@ -150,14 +150,14 @@ group :development, :test do # Debugger which supports rdbg and Shopify Ruby LSP VSCode extension gem "debug", ">= 1.0.0" # RSpec behavioral testing framework for Rails. - gem "rspec-rails", "~> 6.1.3" + gem "rspec-rails", "~> 6.1.4" # Static analysis / linter. gem "rubocop" # Rails add-on for static analysis. gem 'rubocop-performance' gem "rubocop-rails", "~> 2.25.1" # Default rules for Rubocop. - gem "standard", "~> 1.39" + gem "standard", "~> 1.40" # Erb linter. gem "erb_lint" end diff --git a/Gemfile.lock b/Gemfile.lock index 54039a468f..39090ec92c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -141,7 +141,7 @@ GEM activesupport tzinfo coderay (1.1.3) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) coverband (6.1.2) redis (>= 3.0) @@ -243,7 +243,7 @@ GEM faraday-httpclient (1.0.1) faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (1.0.1) + faraday-net_http (1.0.2) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) @@ -315,7 +315,7 @@ GEM activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.7.2) - irb (1.13.2) + irb (1.14.0) rdoc (>= 4.0.0) reline (>= 0.4.2) jbuilder (2.12.0) @@ -373,7 +373,7 @@ GEM method_source (1.1.0) mini_magick (4.13.2) mini_mime (1.1.5) - minitest (5.24.1) + minitest (5.25.1) monetize (1.12.0) money (~> 6.12) money (6.16.0) @@ -383,8 +383,9 @@ GEM monetize (~> 1.9) money (~> 6.13) railties (>= 3.0) - multi_xml (0.6.0) - multipart-post (2.4.0) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + multipart-post (2.4.1) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) mutex_m (0.2.0) @@ -400,7 +401,7 @@ GEM timeout net-smtp (0.5.0) net-protocol - newrelic_rpm (9.12.0) + newrelic_rpm (9.13.0) nio4r (2.7.3) nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) @@ -422,7 +423,7 @@ GEM hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection - omniauth-google-oauth2 (1.1.2) + omniauth-google-oauth2 (1.1.3) jwt (>= 2.0) oauth2 (~> 2.0) omniauth (~> 2.0) @@ -440,8 +441,8 @@ GEM paper_trail (15.1.0) activerecord (>= 6.1) request_store (~> 1.4) - parallel (1.25.1) - parser (3.3.4.0) + parallel (1.26.3) + parser (3.3.4.2) ast (~> 2.4.1) racc pdf-core (0.9.0) @@ -552,7 +553,7 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.4) + rexml (3.3.6) strscan rolify (6.0.1) rouge (4.1.2) @@ -562,13 +563,13 @@ GEM rspec-mocks (~> 3.13.0) rspec-core (3.13.0) rspec-support (~> 3.13.0) - rspec-expectations (3.13.1) + rspec-expectations (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (6.1.3) + rspec-rails (6.1.4) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -577,18 +578,18 @@ GEM rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.64.1) + rubocop (1.65.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) + regexp_parser (>= 2.4, < 3.0) rexml (>= 3.2.5, < 4.0) rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.31.3) + rubocop-ast (1.32.1) parser (>= 3.3.1.0) rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) @@ -648,10 +649,10 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - standard (1.39.2) + standard (1.40.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.64.0) + rubocop (~> 1.65.0) standard-custom (~> 1.0.0) standard-performance (~> 1.4) standard-custom (1.0.2) @@ -660,7 +661,7 @@ GEM standard-performance (1.4.0) lint_roller (~> 1.1) rubocop-performance (~> 1.21.0) - stimulus-rails (1.3.3) + stimulus-rails (1.3.4) railties (>= 6.0.0) stringio (3.1.1) strong_migrations (1.8.0) @@ -668,7 +669,7 @@ GEM strscan (3.1.0) terser (1.2.3) execjs (>= 0.3.0, < 3) - thor (1.3.1) + thor (1.3.2) tilt (2.2.0) timeout (0.4.1) ttfunk (1.7.0) @@ -699,7 +700,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.34) - zeitwerk (2.6.16) + zeitwerk (2.6.17) PLATFORMS arm64-darwin-20 @@ -782,7 +783,7 @@ DEPENDENCIES recaptcha redis (~> 5.2) rolify (~> 6.0) - rspec-rails (~> 6.1.3) + rspec-rails (~> 6.1.4) rubocop rubocop-performance rubocop-rails (~> 2.25.1) @@ -791,7 +792,7 @@ DEPENDENCIES simple_form simplecov sprockets (~> 4.2.1) - standard (~> 1.39) + standard (~> 1.40) stimulus-rails strong_migrations (= 1.8.0) terser diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index d2ee0e734a..74c027ce0e 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -192,3 +192,30 @@ div.low_priority_warning { margin: 5px; text-align: center; } + +.distribution-title { + display: flex; +} + +legend.with-request { + float: none; + width: 80%; + display: inline-block; +} + +div.distribution-request-unit { + display: inline-block; + flex: 1; + text-align: right; + margin-right: 20px; + font-size: 1.5em; +} + +.li-requested { + font-size: 1.5em; + width: 100px; + min-width: 100px; + text-align: right; + margin-right: 20px; + white-space: nowrap; +} diff --git a/app/controllers/distributions_controller.rb b/app/controllers/distributions_controller.rb index e2a10393a9..f7f0e0d62a 100644 --- a/app/controllers/distributions_controller.rb +++ b/app/controllers/distributions_controller.rb @@ -109,7 +109,11 @@ def create # does not match any known Request @distribution.request = Request.find(request_id) end - @distribution.line_items.build if @distribution.line_items.size.zero? + if @distribution.line_items.size.zero? + @distribution.line_items.build + elsif request_id + @distribution.initialize_request_items + end @items = current_organization.items.alphabetized if Event.read_events?(current_organization) inventory = View::Inventory.new(@distribution.organization_id) @@ -166,6 +170,7 @@ def show def edit @distribution = Distribution.includes(:line_items).includes(:storage_location).find(params[:id]) + @distribution.initialize_request_items if (!@distribution.complete? && @distribution.future?) || current_user.has_role?(Role::ORG_ADMIN, current_organization) @distribution.line_items.build if @distribution.line_items.size.zero? @@ -202,6 +207,7 @@ def update else flash[:error] = insufficient_error_message(result.error.message) @distribution.line_items.build if @distribution.line_items.size.zero? + @distribution.initialize_request_items @items = current_organization.items.alphabetized @storage_locations = current_organization.storage_locations.active_locations.alphabetized render :edit diff --git a/app/models/distribution.rb b/app/models/distribution.rb index f8d591e25b..bc5a652e9f 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -102,6 +102,31 @@ def copy_from_donation(donation_id, storage_location_id) self.storage_location = StorageLocation.find(storage_location_id) if storage_location_id end + # This is meant for the Edit page - we will be adding any request items that aren't in the + # distribution for whatever reason, with zero quantity. + def initialize_request_items + return if request.nil? + + item_ids = Set.new + line_items.each do |line_item| + item_request = request.item_requests.find { |r| r.item_id == line_item.item_id } + if item_request + item_ids.add(item_request) + line_item.requested_item = item_request + end + end + + request.item_requests.each do |item_request| + next if item_ids.include?(item_request) + + line_items.new( + requested_item: item_request, + quantity: 0, + item_id: item_request.item_id + ) + end + end + def copy_from_request(request_id) request = Request.find(request_id) self.request = request @@ -110,12 +135,12 @@ def copy_from_request(request_id) self.agency_rep = request.partner_user&.formatted_email self.comment = request.comments self.issued_at = Time.zone.today + 1.day - request.request_items.each do |item| + request.item_requests.each do |item_request| line_items.new( - quantity: item["quantity"], - item: Item.eager_load(:base_item).find_by(organization: request.organization, id: item["item_id"]), - itemizable_id: request.id, - itemizable_type: "Distribution" + requested_item: item_request, + # if there is a custom unit, don't prefill with the quantity - they have to enter it + quantity: item_request.request_unit.present? ? nil : item_request.quantity, + item_id: item_request.item_id ) end end diff --git a/app/models/line_item.rb b/app/models/line_item.rb index e93a52e047..8cdcb79b7c 100644 --- a/app/models/line_item.rb +++ b/app/models/line_item.rb @@ -28,6 +28,10 @@ class LineItem < ApplicationRecord delegate :name, to: :item + # Used in a distribution that was initialized from a request. The `item_request` will be + # populated here. + attr_accessor :requested_item + def quantity_must_be_a_number_within_range if quantity && quantity > MAX_INT errors.add(:quantity, "must be less than #{MAX_INT}") diff --git a/app/services/distribution_update_service.rb b/app/services/distribution_update_service.rb index 5889d2a622..da612d0f95 100644 --- a/app/services/distribution_update_service.rb +++ b/app/services/distribution_update_service.rb @@ -9,6 +9,9 @@ def call perform_distribution_service do @old_issued_at = distribution.issued_at @old_delivery_method = distribution.delivery_method + @params[:line_items_attributes]&.delete_if { |_, a| a[:quantity].to_i.zero? } + + # remove line_items with zero quantity ItemizableUpdateService.call( itemizable: distribution, diff --git a/app/views/distributions/_form.html.erb b/app/views/distributions/_form.html.erb index 2948b48d6c..b72329f950 100644 --- a/app/views/distributions/_form.html.erb +++ b/app/views/distributions/_form.html.erb @@ -33,13 +33,18 @@ <%= f.input :comment, label: "Comment" %>
- Items in this distribution +
+ Items in this distribution + <% if distribution.request %> +
Requested
+ <% end %> +
- <%= render 'line_items/line_item_fields', form: f %> + <%= render 'line_items/line_item_fields', form: f, locals: { show_request_items: true } %>
diff --git a/app/views/line_items/_line_item_fields.html.erb b/app/views/line_items/_line_item_fields.html.erb index 50721acfe8..437f278b12 100644 --- a/app/views/line_items/_line_item_fields.html.erb +++ b/app/views/line_items/_line_item_fields.html.erb @@ -1,24 +1,46 @@ <%= form.simple_fields_for :line_items, defined?(object) ? object : nil do |field| %> + <% requested = field.object.requested_item %>
-
- <%= render partial: "barcode_items/barcode_item_lookup", - locals: { index: field&.options[:child_index] || "new_item" } %> -
-
- + <% if requested.blank? %> +
+ <%= render partial: "barcode_items/barcode_item_lookup", + locals: { index: field&.options[:child_index] || "new_item" } %> +
+
+ + <% end %>
- <%= field.input :item_id, collection: @items, prompt: "Choose an item", include_blank: "", label: false, input_html: { class: "my-0 line_item_name", "data-controller": "select2" } %> + <%= field.input :item_id, + disabled: requested.present?, + collection: @items, prompt: "Choose an item", + include_blank: "", + label: false, + input_html: { class: "my-0 line_item_name", "data-controller": "select2" } %> + <% if requested.present? %> + <%= field.input :item_id, as: :hidden %> + <% end %>
<%= field.input :quantity, - as: :string, - placeholder: "Quantity", - label: false, - input_html: { class: "quantity my-0", data: { quantity: "" } } %> + as: :string, + placeholder: "Quantity", + label: false, + input_html: { class: "quantity my-0", data: { quantity: "" } } %>
+ <% if form.object.respond_to?(:request) && form.object.request %> +
+ <% if requested&.request_unit.present? %> + <%= pluralize(requested.quantity, requested.request_unit) %> + <% elsif requested %> + <%= requested.quantity %> + <% else %> + N/A + <% end %> +
+ <% end %>
diff --git a/app/views/purchases/_purchase_form.html.erb b/app/views/purchases/_purchase_form.html.erb index f2e0d35bb4..f0765e4dd2 100644 --- a/app/views/purchases/_purchase_form.html.erb +++ b/app/views/purchases/_purchase_form.html.erb @@ -27,7 +27,8 @@
<%= f.input :amount_spent, label: "Purchase Total", - wrapper: :input_group %> + wrapper: :input_group, + required: true %>
diff --git a/db/migrate/20240825141541_fix_bad_kits.rb b/db/migrate/20240825141541_fix_bad_kits.rb new file mode 100644 index 0000000000..3aa7ade4be --- /dev/null +++ b/db/migrate/20240825141541_fix_bad_kits.rb @@ -0,0 +1,25 @@ +class FixBadKits < ActiveRecord::Migration[7.1] + def change + return unless Rails.env.production? + + ids = [78, 204,189] + kit_base_item = BaseItem.find_or_create_by!({ + name: 'Kit', + category: 'kit', + partner_key: 'kit' + }) + Kit.where(id: ids).each do |kit| + result = ItemCreateService.new( + organization_id: kit.organization.id, + item_params: { + name: kit.name, + partner_key: kit_base_item.partner_key, + kit_id: kit.id + } + ).call + unless result.success? + raise result.error + end + end + end +end diff --git a/db/migrate/20240830015517_fix_invalid_distribution_event.rb b/db/migrate/20240830015517_fix_invalid_distribution_event.rb new file mode 100644 index 0000000000..cace57fead --- /dev/null +++ b/db/migrate/20240830015517_fix_invalid_distribution_event.rb @@ -0,0 +1,12 @@ +class FixInvalidDistributionEvent < ActiveRecord::Migration[7.1] + def change + return unless Rails.env.production? + + # We are not sure why yet, but this org was able to create a distribution + # that put them at a negative inventory. Later playback of the events with + # validation turned on then raised it as an error. For now we are deleting + # the distribution and event directly. + Event.where(id: 34416, eventable_type: 'Distribution', eventable_id: 75002).first.destroy + Distribution.find(75002).destroy + end +end diff --git a/db/schema.rb b/db/schema.rb index bcc773347a..91483f028f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_07_18_010905) do +ActiveRecord::Schema[7.1].define(version: 2024_08_30_015517) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" diff --git a/spec/factories/items.rb b/spec/factories/items.rb index 4104d0872f..919c5e2a27 100644 --- a/spec/factories/items.rb +++ b/spec/factories/items.rb @@ -35,5 +35,14 @@ trait :inactive do active { false } end + + trait :with_unit do + transient do + unit { "pack" } + end + after(:create) do |item, evaluator| + create(:item_unit, name: evaluator.unit, item: item) + end + end end end diff --git a/spec/factories/requests.rb b/spec/factories/requests.rb index b0ddad8e1d..d8cdc20594 100644 --- a/spec/factories/requests.rb +++ b/spec/factories/requests.rb @@ -28,6 +28,7 @@ def random_request_items request_items { random_request_items } comments { "Urgent" } partner_user { ::User.partner_users.first || create(:partner_user) } + item_requests { [] } # For compatibility we can take in a list of request_items and turn it into a # list of item_requests diff --git a/spec/models/distribution_spec.rb b/spec/models/distribution_spec.rb index bd47938136..5cdab500de 100644 --- a/spec/models/distribution_spec.rb +++ b/spec/models/distribution_spec.rb @@ -250,11 +250,9 @@ item2 = create(:item, name: "Item2", organization: organization) request = create(:request, organization: organization, - partner_user: create(:partner_user), - request_items: [ - { item_id: item1.id, quantity: 15 }, - { item_id: item2.id, quantity: 18 } - ]) + partner_user: create(:partner_user)) + create(:item_request, request: request, item_id: item1.id, quantity: 15) + create(:item_request, request: request, item_id: item2.id, quantity: 18) distribution = Distribution.new distribution.copy_from_request(request.id) expect(distribution.line_items.size).to eq 2 diff --git a/spec/requests/distributions_requests_spec.rb b/spec/requests/distributions_requests_spec.rb index b4adc8fb97..a5b6243cfc 100644 --- a/spec/requests/distributions_requests_spec.rb +++ b/spec/requests/distributions_requests_spec.rb @@ -133,7 +133,19 @@ describe "GET #new" do let!(:partner) { create(:partner, organization: organization) } - let(:request) { create(:request, partner: partner, organization: organization) } + let(:request) { create(:request, partner: partner, organization: organization, item_requests: item_requests) } + let(:items) { + [ + create(:item, :with_unit, organization: organization, name: 'Item 1', unit: 'pack'), + create(:item, organization: organization, name: 'Item 2') + ] + } + let(:item_requests) { + [ + create(:item_request, item: items[0], quantity: 50, request_unit: 'pack'), + create(:item_request, item: items[1], quantity: 25) + ] + } let(:storage_location) { create(:storage_location, :with_items, organization: organization) } let(:default_params) { { request_id: request.id } } @@ -166,6 +178,44 @@ expect(page.css(%(#distribution_storage_location_id option[selected][value="#{storage_location.id}"]))).not_to be_empty end end + + context 'with units' do + before(:each) do + Flipper.enable(:enable_packs) + end + + it 'should behave correctly' do + get new_distribution_path(default_params) + expect(response).to be_successful + page = Nokogiri::HTML(response.body) + + # should have a disabled select and a hidden input + expect(page.css('select[disabled][name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + expect(page.css('input[name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + expect(page.css('select[disabled][name="distribution[line_items_attributes][1][item_id]"]')).not_to be_empty + expect(page.css('input[name="distribution[line_items_attributes][1][item_id]"]')).not_to be_empty + + # input with packs should be blank + expect(page.css('#distribution_line_items_attributes_0_quantity').attr('value')).to eq(nil) + + # input with no packs should show quantity + expect(page.css('#distribution_line_items_attributes_1_quantity').attr('value').value).to eq('25') + end + + context 'with no request' do + it 'should have no inputs' do + get new_distribution_path({}) + expect(response).to be_successful + page = Nokogiri::HTML(response.body) + + # blank input shown + expect(page.css('select[name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + expect(page.css('#distribution_line_items_attributes_0_quantity').attr('value')).to eq(nil) + # in the template + expect(page.css('select[name="distribution[line_items_attributes][1][item_id]"]')).not_to be_empty + end + end + end end describe "GET #show" do @@ -414,6 +464,76 @@ expect(response.body).not_to include("You’ve had an audit since this distribution was started.") end + context 'with units' do + let!(:request) { + create(:request, + partner: partner, + organization: organization, + distribution_id: distribution.id, + item_requests: item_requests) + } + let(:items) { + [ + create(:item, :with_unit, organization: organization, name: 'Item 1', unit: 'pack'), + create(:item, organization: organization, name: 'Item 2'), + create(:item, organization: organization, name: 'Item 3') + ] + } + let!(:item_requests) { + [ + create(:item_request, item: items[0], quantity: 50, request_unit: 'pack'), + create(:item_request, item: items[1], quantity: 25) + ] + } + before(:each) do + Flipper.enable(:enable_packs) + create(:line_item, itemizable: distribution, item_id: items[0].id, quantity: 25) + create(:line_item, itemizable: distribution, item_id: items[2].id, quantity: 10) + end + + it 'should behave correctly' do + get edit_distribution_path(id: distribution.id) + expect(response).to be_successful + page = Nokogiri::HTML(response.body) + + # should have a regular select and no hidden input + expect(page.css('select[disabled][name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + expect(page.css('input[name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + + # should have a regular select and no hidden input + expect(page.css('select[name="distribution[line_items_attributes][1][item_id]"]')).not_to be_empty + expect(page.css('select[disabled][name="distribution[line_items_attributes][1][item_id]"]')).to be_empty + expect(page.css('input[name="distribution[line_items_attributes][1][item_id]"]')).to be_empty + + # should have a disabled select and a hidden input + expect(page.css('select[disabled][name="distribution[line_items_attributes][2][item_id]"]')).not_to be_empty + expect(page.css('input[name="distribution[line_items_attributes][2][item_id]"]')).not_to be_empty + + # existing inputs should show numbers + expect(page.css('#distribution_line_items_attributes_0_quantity').attr('value').value).to eq('25') + expect(page.css('#distribution_line_items_attributes_1_quantity').attr('value').value).to eq('10') + + # input from request should show 0 + expect(page.css('#distribution_line_items_attributes_2_quantity').attr('value').value).to eq('0') + end + + context 'with no request' do + it 'should have everything enabled' do + request.destroy + get edit_distribution_path(id: distribution.id) + expect(response).to be_successful + page = Nokogiri::HTML(response.body) + + expect(page.css('select[name="distribution[line_items_attributes][0][item_id]"]')).not_to be_empty + expect(page.css('select[disabled][name="distribution[line_items_attributes][0][item_id]"]')).to be_empty + expect(page.css('input[name="distribution[line_items_attributes][0][item_id]"]')).to be_empty + expect(page.css('select[name="distribution[line_items_attributes][1][item_id]"]')).not_to be_empty + expect(page.css('select[disabled][name="distribution[line_items_attributes][1][item_id]"]')).to be_empty + expect(page.css('input[name="distribution[line_items_attributes][1][item_id]"]')).to be_empty + end + end + end + # Bug fix #4537 context "when distribution sets storage location total inventory to zero" do let(:item1) { create(:item, name: "Item 1", organization: organization) } diff --git a/spec/system/distribution_system_spec.rb b/spec/system/distribution_system_spec.rb index 956a2a3111..05ebb31492 100644 --- a/spec/system/distribution_system_spec.rb +++ b/spec/system/distribution_system_spec.rb @@ -596,6 +596,8 @@ items = storage_location.items.pluck(:id).sample(2) request_items = [{ "item_id" => items[0], "quantity" => 10 }, { "item_id" => items[1], "quantity" => 10 }] @request = create :request, organization: organization, request_items: request_items + create(:item_request, request: @request, item_id: items[0], quantity: 10) + create(:item_request, request: @request, item_id: items[1], quantity: 10) visit request_path(id: @request.id) click_on "Fulfill request" @@ -629,6 +631,8 @@ items = storage_location.items.pluck(:id).sample(2) request_items = [{ "item_id" => items[0], "quantity" => 1000000 }, { "item_id" => items[1], "quantity" => 10 }] @request = create :request, organization: organization, request_items: request_items + create(:item_request, request: @request, item_id: items[0], quantity: 1000000) + create(:item_request, request: @request, item_id: items[1], quantity: 10) visit request_path(id: @request.id) click_on "Fulfill request"