From e0cea9006d82d216d0770d2b36b4f76949a8bfa0 Mon Sep 17 00:00:00 2001 From: Vasili Kachalko Date: Tue, 24 Sep 2024 15:24:29 +0200 Subject: [PATCH] add eligibility bulk assignment --- .../stylesheets/admin/page-applications.scss | 5 +++ ...ility_assignment_collections_controller.rb | 23 ++++++++++++++ .../admin/form_answers_controller.rb | 12 +++++-- ...enant_assignment_collections_controller.rb | 2 +- app/controllers/concerns/form_answer_mixin.rb | 5 +-- .../eligibility_assignment_collection.rb | 31 +++++++++++++++++++ ...ligibility_assignment_collection_policy.rb | 5 +++ .../_bulk_assignment_button_top.html.slim | 3 ++ .../bulk_assign_eligibility.html.slim | 24 ++++++++++++++ config/routes.rb | 3 +- forms/nominations_bulk_action_form.rb | 21 ++++++++++++- 11 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 app/controllers/admin/eligibility_assignment_collections_controller.rb create mode 100644 app/models/eligibility_assignment_collection.rb create mode 100644 app/policies/eligibility_assignment_collection_policy.rb create mode 100644 app/views/admin/form_answers/bulk_assign_eligibility.html.slim diff --git a/app/assets/stylesheets/admin/page-applications.scss b/app/assets/stylesheets/admin/page-applications.scss index 4183c8e5c..d5e740017 100644 --- a/app/assets/stylesheets/admin/page-applications.scss +++ b/app/assets/stylesheets/admin/page-applications.scss @@ -593,3 +593,8 @@ .js-remove-audit-certificate-link span { margin-top: 0; } + +.govuk-bulk-error-message { + margin-top: 20px; + color: rgb(212, 53, 28); +} diff --git a/app/controllers/admin/eligibility_assignment_collections_controller.rb b/app/controllers/admin/eligibility_assignment_collections_controller.rb new file mode 100644 index 000000000..ff9b9ac85 --- /dev/null +++ b/app/controllers/admin/eligibility_assignment_collections_controller.rb @@ -0,0 +1,23 @@ +class Admin::EligibilityAssignmentCollectionsController < Admin::BaseController + def create + @form = EligibilityAssignmentCollection.new(create_params) + authorize @form, :create? + + @form.subject = current_subject + + if @form.save + redirect_to admin_form_answers_path(year: params[:year], search_id: params[:search_id]), notice: @form.notice_message + else + # Ensure form_answer_ids is an array + @form.form_answer_ids = @form.form_answer_ids.split(",") if @form.form_answer_ids.is_a?(String) + render "admin/form_answers/bulk_assign_eligibility" + end + end + + private + + def create_params + params.require(:eligibility_assignment_collection) + .permit(:form_answer_ids, :state) + end +end diff --git a/app/controllers/admin/form_answers_controller.rb b/app/controllers/admin/form_answers_controller.rb index be8c210a7..60269cce8 100644 --- a/app/controllers/admin/form_answers_controller.rb +++ b/app/controllers/admin/form_answers_controller.rb @@ -262,8 +262,8 @@ def bulk_assign_lieutenants # get form_answer_ids after validation error params[:lieutenant_assignment_collection][:form_answer_ids] end + @form = LieutenantAssignmentCollection.new(form_answer_ids: form_answer_ids, params: bulk_assign_params) - @form.form_answer_ids = form_answer_ids end def bulk_assign_assessors @@ -271,11 +271,19 @@ def bulk_assign_assessors form_answer_ids = params[:bulk_action][:ids] @form = AssessorAssignmentCollection.new(form_answer_ids: form_answer_ids) - @form.form_answer_ids = form_answer_ids end def bulk_assign_eligibility authorize :eligibility_assignment_collection, :create? + + form_answer_ids = if params[:bulk_action] + params[:bulk_action][:ids] + elsif params[:lieutenant_assignment_collection] + # get form_answer_ids after validation error + params[:lieutenant_assignment_collection][:form_answer_ids] + end + + @form = EligibilityAssignmentCollection.new(form_answer_ids: form_answer_ids) end # / batch actions diff --git a/app/controllers/admin/lieutenant_assignment_collections_controller.rb b/app/controllers/admin/lieutenant_assignment_collections_controller.rb index 0fd4b52e3..35084e808 100644 --- a/app/controllers/admin/lieutenant_assignment_collections_controller.rb +++ b/app/controllers/admin/lieutenant_assignment_collections_controller.rb @@ -18,6 +18,6 @@ def create def create_params params.require(:lieutenant_assignment_collection) - .permit(:form_answer_ids, :ceremonial_county_id, :year) + .permit(:form_answer_ids, :ceremonial_county_id) end end diff --git a/app/controllers/concerns/form_answer_mixin.rb b/app/controllers/concerns/form_answer_mixin.rb index c77203563..1be3bc11a 100644 --- a/app/controllers/concerns/form_answer_mixin.rb +++ b/app/controllers/concerns/form_answer_mixin.rb @@ -100,7 +100,7 @@ def save_or_load_search! :year, :bulk_assign_lieutenants, :bulk_assign_assessors, - # :bulk_assign_eligibility, + :bulk_assign_eligibility, search: {}, bulk_action: { ids: [] } ) @@ -110,7 +110,8 @@ def save_or_load_search! unless @processor.valid? # raise "Invalid bulk action parameters: #{params.to_yaml}\nErrors: #{@processor.errors.full_messages.to_yaml}" - redirect_to admin_form_answers_path(year: params[:year], search_id: @processor.search_id), notice: "You must select at least one group from the list below before clicking a bulk action button." and return + flash[:bulk_error] = @processor.base_error_messages + redirect_to admin_form_answers_path(year: params[:year], search_id: @processor.search_id) and return end redirect_url = @processor.redirect_url diff --git a/app/models/eligibility_assignment_collection.rb b/app/models/eligibility_assignment_collection.rb new file mode 100644 index 000000000..7c781d821 --- /dev/null +++ b/app/models/eligibility_assignment_collection.rb @@ -0,0 +1,31 @@ +class EligibilityAssignmentCollection < AssignmentCollection + VALID_STATES = %w[submitted admin_pending_eligibility].freeze + + + attribute :state, String + + validates :state, presence: true, inclusion: { in: FormAnswerStateMachine::ELIGIBILITY_STATES.map(&:to_s) } + + validate :form_answers_state_validation + + def save + return unless valid? + form_answers.update_all(state: state) + end + + def notice_message + if ids.length > 1 + "Groups have" + else + "Group has" + end.concat " been assigned the #{state} status." + end + + private + + def form_answers_state_validation + unless form_answers.all? { |form_answer| VALID_STATES.include?(form_answer.state) } + errors.add(:form_answer_ids, "To assign the eligibility status, you must only select groups that currently have ‘Nomination submitted’ or ‘Eligibility pending’ status.") + end + end +end diff --git a/app/policies/eligibility_assignment_collection_policy.rb b/app/policies/eligibility_assignment_collection_policy.rb new file mode 100644 index 000000000..e6391b3a3 --- /dev/null +++ b/app/policies/eligibility_assignment_collection_policy.rb @@ -0,0 +1,5 @@ +class EligibilityAssignmentCollectionPolicy < ApplicationPolicy + def create? + admin? + end +end diff --git a/app/views/admin/form_answers/_bulk_assignment_button_top.html.slim b/app/views/admin/form_answers/_bulk_assignment_button_top.html.slim index e84b19e32..e1d559ad1 100644 --- a/app/views/admin/form_answers/_bulk_assignment_button_top.html.slim +++ b/app/views/admin/form_answers/_bulk_assignment_button_top.html.slim @@ -4,6 +4,9 @@ strong ' Bulk actions: ' select groups from the list below and click an appropriate bulk action button. + - if flash[:bulk_error].present? + p.govuk-body.govuk-bulk-error-message + = flash[:bulk_error] .bulk-assignment-buttons-container = f.submit "Bulk assign to Lord Lieutenancy office", class: "govuk-button bulk-assign-lieutenants-link", name: "bulk_assign_lieutenants" = f.submit "Bulk assign to national assessor sub-group", class: "govuk-button bulk-assign-assessors-link", name: "bulk_assign_assessors" diff --git a/app/views/admin/form_answers/bulk_assign_eligibility.html.slim b/app/views/admin/form_answers/bulk_assign_eligibility.html.slim new file mode 100644 index 000000000..e1bf5fcc4 --- /dev/null +++ b/app/views/admin/form_answers/bulk_assign_eligibility.html.slim @@ -0,0 +1,24 @@ + +h3.govuk-heading-m + | Assign eligibility status to selected groups + += simple_form_for [namespace_name, @form] do |f| + .govuk-form-group.primary-subgroup-group + = f.input :state, + as: :radio_buttons, + collection: FormAnswerStateMachine::ELIGIBILITY_STATES.map { |s| [t(s, scope: "form_answers.state"), s] }, + input_html: { class: "admin-eligibility-option" }, + label: "Select the eligibility status", + label_html: { class: "govuk-!-font-size-19 govuk-!-margin-bottom-0" } + - if @form.errors[:sub_group].any? + .govuk-error-message + | Please select a national assessor sub-group + + = f.hidden_field :search_id, value: params[:search_id], name: :search_id + = f.hidden_field :year, value: params[:year], name: :year + + = f.hidden_field :form_answer_ids, value: @form.form_answer_ids.join(",") + + .govuk-button-group + = f.submit "Bulk assign eligibility status", class: "govuk-button" + = link_to "Cancel", [namespace_name, :form_answers, year: params[:year], search_id: params[:search_id]], class: "govuk-link" diff --git a/config/routes.rb b/config/routes.rb index 28f146f0e..7d949f8d1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -223,8 +223,6 @@ %w[bulk_assign_lieutenants bulk_assign_assessors bulk_assign_eligibility].each do |action| get action post action - get "#{action}_confirm" - post "#{action}_confirm" end end @@ -271,6 +269,7 @@ resources :lieutenant_assignment_collections, only: [:create] resources :assessor_assignment_collections, only: [:create] + resources :eligibility_assignment_collections, only: [:create] resource :account, only: [:edit] do collection do diff --git a/forms/nominations_bulk_action_form.rb b/forms/nominations_bulk_action_form.rb index e9f3ae977..031f8423e 100644 --- a/forms/nominations_bulk_action_form.rb +++ b/forms/nominations_bulk_action_form.rb @@ -15,14 +15,20 @@ def valid? end case @kind - when "lieutenants", "assessors", "eligibility" + when "lieutenants", "assessors" params[:bulk_action].present? + when "eligibility" + params[:bulk_action].present? && form_answers_eligible_for_state_change? else @errors.add(:bulk_base, "Invalid bulk action type.") false end end + def base_error_messages + @errors[:bulk_base].join(" ") + end + def redirect_url case @kind when "lieutenants" @@ -47,6 +53,8 @@ def determine_kind end end + private + def save_search_and_clean_params(params) if params[:search] && params[:search][:search_filter] != FormAnswerSearch.default_search[:search_filter] search = NominationSearch.create(serialized_query: params[:search].to_json) @@ -58,4 +66,15 @@ def save_search_and_clean_params(params) params end + + def form_answers_eligible_for_state_change? + if FormAnswer.where(id: params[:bulk_action][:ids]).all? do |form_answer| + EligibilityAssignmentCollection::VALID_STATES.include?(form_answer.state) + end + true + else + @errors.add(:bulk_base, "To assign the eligibility status, you must only select groups that currently have ‘Nomination submitted’ or ‘Eligibility pending’ status.") + false + end + end end