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" %>