diff --git a/app/controllers/partners/family_requests_controller.rb b/app/controllers/partners/family_requests_controller.rb index ff91b4b9bc..efa0f45eb3 100644 --- a/app/controllers/partners/family_requests_controller.rb +++ b/app/controllers/partners/family_requests_controller.rb @@ -29,8 +29,8 @@ def create family_requests_attributes = 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 } end - create_service = Partners::FamilyRequestCreateService.new( + request_type: "child", partner_user_id: current_user.id, family_requests_attributes: family_requests_attributes, for_families: true diff --git a/app/controllers/partners/individuals_requests_controller.rb b/app/controllers/partners/individuals_requests_controller.rb index dff8560914..015d88035e 100644 --- a/app/controllers/partners/individuals_requests_controller.rb +++ b/app/controllers/partners/individuals_requests_controller.rb @@ -10,6 +10,7 @@ def new def create create_service = Partners::FamilyRequestCreateService.new( + request_type: "individual", partner_user_id: current_user.id, comments: individuals_request_params[:comments], family_requests_attributes: individuals_request_params[:items_attributes]&.values diff --git a/app/controllers/partners/requests_controller.rb b/app/controllers/partners/requests_controller.rb index eec3c8cf4a..0763d00e3f 100644 --- a/app/controllers/partners/requests_controller.rb +++ b/app/controllers/partners/requests_controller.rb @@ -20,6 +20,7 @@ def show def create create_service = Partners::RequestCreateService.new( + request_type: "quantity", partner_user_id: current_user.id, comments: partner_request_params[:comments], item_requests_attributes: partner_request_params[:item_requests_attributes]&.values || [] diff --git a/app/controllers/requests_controller.rb b/app/controllers/requests_controller.rb index d44f022e3d..1593b68bd7 100644 --- a/app/controllers/requests_controller.rb +++ b/app/controllers/requests_controller.rb @@ -13,10 +13,12 @@ def index @calculate_product_totals = RequestsTotalItemsService.new(requests: @requests).calculate @items = current_organization.items.alphabetized @partners = current_organization.partners.order(:name) - @statuses = Request.statuses.transform_keys(&:humanize) + @selected_partner = filter_params[:by_partner] @partner_users = User.where(id: @paginated_requests.pluck(:partner_user_id)) + @request_types = Request.request_types.transform_keys(&:humanize) + @selected_request_type = filter_params[:by_request_type] @selected_request_item = filter_params[:by_request_item_id] - @selected_partner = filter_params[:by_partner] + @statuses = Request.statuses.transform_keys(&:humanize) @selected_status = filter_params[:by_status] respond_to do |format| @@ -57,6 +59,6 @@ def load_items def filter_params return {} unless params.key?(:filters) - params.require(:filters).permit(:by_request_item_id, :by_partner, :by_status) + params.require(:filters).permit(:by_request_item_id, :by_partner, :by_status, :by_request_type) end end diff --git a/app/models/request.rb b/app/models/request.rb index c6963aeeb3..56959a0a10 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -7,6 +7,7 @@ # discard_reason :text # discarded_at :datetime # request_items :jsonb +# request_type :string # status :integer default("pending") # created_at :datetime not null # updated_at :datetime not null @@ -31,6 +32,7 @@ class Request < ApplicationRecord has_many :child_item_requests, through: :item_requests enum status: { pending: 0, started: 1, fulfilled: 2, discarded: 3 }, _prefix: true + enum request_type: %w[quantity individual child].map { |v| [v, v] }.to_h validates :distribution_id, uniqueness: true, allow_nil: true before_save :sanitize_items_data @@ -42,6 +44,7 @@ class Request < ApplicationRecord scope :by_partner, ->(partner_id) { where(partner_id: partner_id) } # status scope to allow filtering by status scope :by_status, ->(status) { where(status: status) } + scope :by_request_type, ->(request_type) { where(request_type: request_type) } scope :during, ->(range) { where(created_at: range) } scope :for_csv_export, ->(organization, *) { where(organization: organization) @@ -57,6 +60,10 @@ def user_email partner_user_id ? User.find_by(id: partner_user_id).email : Partner.find_by(id: partner_id).email end + def request_type_label + request_type&.first&.capitalize + end + private def sanitize_items_data diff --git a/app/services/exports/export_request_service.rb b/app/services/exports/export_request_service.rb index e7bfba43af..0fba4d1bd9 100644 --- a/app/services/exports/export_request_service.rb +++ b/app/services/exports/export_request_service.rb @@ -46,6 +46,9 @@ def base_table "Requestor" => ->(request) { request.partner.name }, + "Type" => ->(request) { + request.request_type&.humanize + }, "Status" => ->(request) { request.status.humanize } diff --git a/app/services/partners/family_request_create_service.rb b/app/services/partners/family_request_create_service.rb index e181d3e2f7..b967d20003 100644 --- a/app/services/partners/family_request_create_service.rb +++ b/app/services/partners/family_request_create_service.rb @@ -8,7 +8,7 @@ class FamilyRequestCreateService attr_reader :partner_user_id, :comments, :family_requests_attributes, :partner_request - def initialize(partner_user_id:, family_requests_attributes:, comments: nil, for_families: false) + def initialize(request_type:, partner_user_id:, family_requests_attributes:, comments: nil, for_families: false) @partner_user_id = partner_user_id @comments = comments @family_requests_attributes = family_requests_attributes.presence || [] @@ -19,6 +19,7 @@ def call return self unless valid? request_create_svc = Partners::RequestCreateService.new( + request_type: request_type, partner_user_id: partner_user_id, comments: comments, for_families: @for_families, @@ -72,5 +73,13 @@ def convert_person_count_to_item_quantity(item_id:, person_count:) def included_items_by_id @included_items_by_id ||= Item.where(id: family_requests_attributes.pluck(:item_id)).index_by(&:id) end + + def request_type + if @for_families + "child" + else + "individual" + end + end end end diff --git a/app/services/partners/request_create_service.rb b/app/services/partners/request_create_service.rb index e5c4058083..a3709b5c4e 100644 --- a/app/services/partners/request_create_service.rb +++ b/app/services/partners/request_create_service.rb @@ -2,9 +2,10 @@ module Partners class RequestCreateService include ServiceObjectErrorsMixin - attr_reader :partner_request + attr_reader :partner_request, :request_type - def initialize(partner_user_id:, comments: nil, for_families: false, item_requests_attributes: [], additional_attrs: {}) + def initialize(request_type:, partner_user_id:, comments: nil, for_families: false, item_requests_attributes: [], additional_attrs: {}) + @request_type = request_type @partner_user_id = partner_user_id @comments = comments @for_families = for_families @@ -13,7 +14,9 @@ def initialize(partner_user_id:, comments: nil, for_families: false, item_reques end def call - @partner_request = ::Request.new(partner_id: partner.id, + @partner_request = ::Request.new( + request_type: request_type, + partner_id: partner.id, organization_id: organization_id, comments: comments, partner_user_id: partner_user_id) diff --git a/app/views/partners/family_requests/new.html.erb b/app/views/partners/family_requests/new.html.erb index afe0256c3a..b6259dac2b 100644 --- a/app/views/partners/family_requests/new.html.erb +++ b/app/views/partners/family_requests/new.html.erb @@ -81,7 +81,7 @@
<% end %> diff --git a/app/views/requests/_request_row.html.erb b/app/views/requests/_request_row.html.erb index dbdbceb467..86fc67eac5 100644 --- a/app/views/requests/_request_row.html.erb +++ b/app/views/requests/_request_row.html.erb @@ -12,6 +12,9 @@ <%= request_row.comments %> + + <%= request_row.request_type_label %> + <%= render partial: "status", locals: {status: request_row.status} %> diff --git a/app/views/requests/index.html.erb b/app/views/requests/index.html.erb index 5e02fc6b4e..397a0ae05a 100644 --- a/app/views/requests/index.html.erb +++ b/app/views/requests/index.html.erb @@ -47,6 +47,9 @@ <%= filter_select(scope: :by_partner, collection: @partners, selected: @selected_partner) %> <% end %> +
+ <%= filter_select(scope: :by_request_type, collection: @request_types, key: :last, value: :first, selected: @selected_request_type) %> +
<%= filter_select(scope: :by_status, collection: @statuses, key: :last, value: :first, selected: @selected_status) %>
@@ -92,6 +95,7 @@ Request Sender # of Items (Request Limit) Comments + Type Status Actions diff --git a/app/views/requests/show.html.erb b/app/views/requests/show.html.erb index f7e4ab98b1..7b5937d649 100644 --- a/app/views/requests/show.html.erb +++ b/app/views/requests/show.html.erb @@ -37,6 +37,7 @@ Request was sent by: Request Sender: + Request Type: Request Status: Comments: @@ -45,6 +46,7 @@ <%= @request.partner.name %> <%= @request.partner_user&.formatted_email %> + <%= @request.request_type_label %> <%= render partial: "status", locals: {status: @request.status} %> <%= @request.comments || 'None' %> diff --git a/db/migrate/20240315190152_add_type_to_requests.rb b/db/migrate/20240315190152_add_type_to_requests.rb new file mode 100644 index 0000000000..335f3908bc --- /dev/null +++ b/db/migrate/20240315190152_add_type_to_requests.rb @@ -0,0 +1,5 @@ +class AddTypeToRequests < ActiveRecord::Migration[7.0] + def change + add_column :requests, :request_type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 66a524a7f3..0b7ba42b71 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -737,6 +737,7 @@ t.datetime "discarded_at", precision: nil t.text "discard_reason" t.integer "partner_user_id" + t.string "request_type" t.index ["discarded_at"], name: "index_requests_on_discarded_at" t.index ["distribution_id"], name: "index_requests_on_distribution_id", unique: true t.index ["organization_id"], name: "index_requests_on_organization_id" diff --git a/spec/factories/requests.rb b/spec/factories/requests.rb index 57dc94cf28..aa3930c82d 100644 --- a/spec/factories/requests.rb +++ b/spec/factories/requests.rb @@ -7,6 +7,7 @@ # discard_reason :text # discarded_at :datetime # request_items :jsonb +# request_type :string # status :integer default("pending") # created_at :datetime not null # updated_at :datetime not null @@ -42,6 +43,18 @@ def random_request_items status { 'pending' } end + trait :quantity do + request_type { 'quantity' } + end + + trait :individual do + request_type { 'individual' } + end + + trait :child do + request_type { 'child' } + end + trait :with_duplicates do request_items { # get 3 unique item ids diff --git a/spec/models/request_spec.rb b/spec/models/request_spec.rb index 512cac62e4..c6032255e2 100644 --- a/spec/models/request_spec.rb +++ b/spec/models/request_spec.rb @@ -7,6 +7,7 @@ # discard_reason :text # discarded_at :datetime # request_items :jsonb +# request_type :string # status :integer default("pending") # created_at :datetime not null # updated_at :datetime not null @@ -56,6 +57,16 @@ end end + describe "request_type_label" do + let(:id_one) { create(:item).id } + let(:id_two) { create(:item).id } + let(:request) { create(:request, request_items: [{ item_id: id_one, quantity: 15 }, { item_id: id_two, quantity: 18 }], request_type: "individual") } + + it "returns the the first letter of the request_type capitalized" do + expect(request.request_type_label).to eq("I") + end + end + describe "versioning" do it { is_expected.to be_versioned } end diff --git a/spec/services/exports/export_request_service_spec.rb b/spec/services/exports/export_request_service_spec.rb index b36732996c..03adab607e 100644 --- a/spec/services/exports/export_request_service_spec.rb +++ b/spec/services/exports/export_request_service_spec.rb @@ -56,7 +56,7 @@ let(:expected_headers) do expected_headers_item_headers = [item_2t, item_3t].map(&:name).sort expected_headers_item_headers << Exports::ExportRequestService::DELETED_ITEMS_COLUMN_HEADER - %w(Date Requestor Status) + expected_headers_item_headers + %w(Date Requestor Type Status) + expected_headers_item_headers end it "includes headers as the first row with ordered item names alphabetically with deleted item included at the end" do