diff --git a/app/controllers/partners/family_requests_controller.rb b/app/controllers/partners/family_requests_controller.rb index 6a74bdcdd6..c13c88d27f 100644 --- a/app/controllers/partners/family_requests_controller.rb +++ b/app/controllers/partners/family_requests_controller.rb @@ -29,7 +29,7 @@ def create if create_service.errors.none? redirect_to partners_request_path(create_service.partner_request), notice: "Requested items successfully!" else - redirect_to new_partners_family_request_path, error: "Request failed! #{create_service.errors.map { |error| error.message.to_s }}}" + redirect_to new_partners_family_request_path, error: create_service.errors.map { |error| error.message.to_s }.join(",").to_s end end @@ -56,20 +56,23 @@ def validate private def build_family_requests_attributes(params) - children_ids = [] + child_ids = params.keys.grep(/^child-/).map { |key| key.split('-').last } - params.each do |key, _| - is_child, id = key.split('-') - if is_child == 'child' - children_ids << id - end - end - - children = current_partner.children.where(id: children_ids).joins(:requested_items).select('children.*', :item_id) + children_grouped_by_item_id = current_partner + .children + .where(id: child_ids) + .joins(:requested_items) + .select('children.*', 'items.id as item_id', + 'items.name as item_name', + 'items.visible_to_partners') + .group_by(&:item_id) - children_grouped_by_item_id = children.group_by(&:item_id) children_grouped_by_item_id.map do |item_id, item_requested_children| - { item_id: item_id, person_count: item_requested_children.size, children: item_requested_children } + { + item_id: item_id, + person_count: item_requested_children.size, + children: item_requested_children + } end end end diff --git a/app/services/partners/family_request_create_service.rb b/app/services/partners/family_request_create_service.rb index 8640ed249a..d11bb56975 100644 --- a/app/services/partners/family_request_create_service.rb +++ b/app/services/partners/family_request_create_service.rb @@ -57,6 +57,8 @@ def valid? errors.add(:base, 'detected a unknown item_id') end + check_for_item_visibility + errors.none? end @@ -71,6 +73,37 @@ def item_requests_attributes end end + # If requested item(s) isn't visible to partners, + # an error specifying which item is not available is raised + def check_for_item_visibility + invisible_items = item_requests_attributes.select { |attr| + !included_items_by_id[attr[:item_id]].nil? && + !included_items_by_id[attr[:item_id]].visible_to_partners + } + + unless invisible_items.empty? + + item_errors = invisible_items.map do |item| + item_name = included_items_by_id[item[:item_id]].name + + children_names = item[:children].map { |c| "#{c.first_name} #{c.last_name}" }.join(", ") + + "\"#{item_name}\" requested for #{children_names} is not currently available for request." + end + + joined_errors = item_errors.join(", ") + + # don't want to show a memflash error + if joined_errors.length >= Memflash.threshold + truncated_errors = joined_errors[0...(Memflash.threshold - 10)] + errors.add(:base, "#{truncated_errors}...") + else + errors.add(:base, joined_errors) + end + + end + end + def convert_person_count_to_item_quantity(item_id:, person_count:) item = included_items_by_id[item_id.to_i] diff --git a/app/views/layouts/partners/application.html.erb b/app/views/layouts/partners/application.html.erb index b1e6f1129a..35c342be27 100644 --- a/app/views/layouts/partners/application.html.erb +++ b/app/views/layouts/partners/application.html.erb @@ -66,7 +66,7 @@
<% flash.each do |key, value| %> <% end %> diff --git a/spec/requests/partners/family_requests_requests_spec.rb b/spec/requests/partners/family_requests_requests_spec.rb index 5aed5137a6..4a1a1114fb 100644 --- a/spec/requests/partners/family_requests_requests_spec.rb +++ b/spec/requests/partners/family_requests_requests_spec.rb @@ -48,6 +48,41 @@ expect(subject).to redirect_to(partners_requests_path) end + it "does not allow requesting non-visible items" do + partner.update!(status: :approved) + + # update child item to not be visible to partners + i = Item.first + i.update!(visible_to_partners: false) + + subject + + child_with_unavailable_item = children[0] + expected = "\"#{i.name}\" requested for #{child_with_unavailable_item.first_name} #{child_with_unavailable_item.last_name} is not currently available for request." + + expect(response.request.flash[:error]).to eql expected + end + + it "does not allow requesting non-visible items for multiple children" do + partner.update!(status: :approved) + + # update child item to not be visible to partners + i = Item.first + i.update!(visible_to_partners: false) + + children[1].update(requested_item_ids: [i.id]) + + subject + + children_with_unavailable_item = children[0..1] + + child_formatting = children_with_unavailable_item.map { |c| "#{c.first_name} #{c.last_name}" }.join(", ") + + expected = "\"#{i.name}\" requested for #{child_formatting} is not currently available for request." + + expect(response.request.flash[:error]).to eql expected + end + it "submits the request" do partner.update!(status: :approved)