From 91374d7c881c268ec5b1b638ee2583ca438f6493 Mon Sep 17 00:00:00 2001 From: starswan Date: Wed, 2 Oct 2024 15:41:50 +0100 Subject: [PATCH] Add reason when extending deadline --- .../vacancies/extend_deadline_controller.rb | 2 +- .../job_listing/extend_deadline_form.rb | 5 +- app/models/vacancy.rb | 1 + .../vacancies/extend_deadline/show.html.slim | 8 +++ config/analytics.yml | 2 + config/locales/activerecord.yml | 4 +- config/locales/publishers.yml | 6 +++ ...2105609_add_extension_reason_to_vacancy.rb | 6 +++ db/schema.rb | 4 +- .../job_listing/extend_deadline_form_spec.rb | 2 + .../import_from_vacancy_source_job_spec.rb | 2 + .../vacancies/extend_deadline_spec.rb | 1 + .../publishers_can_extend_a_deadline_spec.rb | 49 ++++++++++++------- 13 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 db/migrate/20241002105609_add_extension_reason_to_vacancy.rb diff --git a/app/controllers/publishers/vacancies/extend_deadline_controller.rb b/app/controllers/publishers/vacancies/extend_deadline_controller.rb index e0e7a41aab..55f132c00a 100644 --- a/app/controllers/publishers/vacancies/extend_deadline_controller.rb +++ b/app/controllers/publishers/vacancies/extend_deadline_controller.rb @@ -34,7 +34,7 @@ def form_attributes def form_params params.require(:publishers_job_listing_extend_deadline_form) - .permit(:expires_at, :expiry_time, :start_date_type, :starts_on, :earliest_start_date, :latest_start_date, :other_start_date_details) + .permit(:expires_at, :expiry_time, :start_date_type, :starts_on, :earliest_start_date, :latest_start_date, :other_start_date_details, :extension_reason, :other_extension_reason_details) .merge(previous_deadline: vacancy.expires_at) end diff --git a/app/form_models/publishers/job_listing/extend_deadline_form.rb b/app/form_models/publishers/job_listing/extend_deadline_form.rb index 9253234587..332814687a 100644 --- a/app/form_models/publishers/job_listing/extend_deadline_form.rb +++ b/app/form_models/publishers/job_listing/extend_deadline_form.rb @@ -2,7 +2,7 @@ class Publishers::JobListing::ExtendDeadlineForm < BaseForm include ActiveRecord::AttributeAssignment include DateAttributeAssignment - attr_accessor :expiry_time, :other_start_date_details, :start_date_type, :previous_deadline + attr_accessor :expiry_time, :other_start_date_details, :start_date_type, :previous_deadline, :extension_reason, :other_extension_reason_details attr_reader :expires_at, :starts_on, :earliest_start_date, :latest_start_date validates :expires_at, date: { on_or_after: :now, on_or_before: :far_future, after: :previous_deadline } @@ -12,6 +12,7 @@ class Publishers::JobListing::ExtendDeadlineForm < BaseForm validates :earliest_start_date, presence: true, date: { on_or_after: :today, on_or_before: :far_future, after: :expires_at, before: :latest_start_date }, if: -> { start_date_type == "date_range" } validates :latest_start_date, presence: true, date: { on_or_after: :today, on_or_before: :far_future, after: :earliest_start_date }, if: -> { start_date_type == "date_range" } validates :other_start_date_details, presence: true, if: -> { start_date_type == "other" } + validates :extension_reason, inclusion: { in: Vacancy.extension_reasons.keys } def attributes_to_save { @@ -21,6 +22,8 @@ def attributes_to_save earliest_start_date: (earliest_start_date if start_date_type == "date_range"), latest_start_date: (latest_start_date if start_date_type == "date_range"), other_start_date_details: (other_start_date_details if start_date_type == "other"), + extension_reason: extension_reason, + other_extension_reason_details: other_extension_reason_details, } end diff --git a/app/models/vacancy.rb b/app/models/vacancy.rb index 3d35b9ebf7..dad0894fb1 100644 --- a/app/models/vacancy.rb +++ b/app/models/vacancy.rb @@ -53,6 +53,7 @@ class Vacancy < ApplicationRecord enum start_date_type: { specific_date: 0, date_range: 1, other: 2, undefined: 3, asap: 4 } enum status: { published: 0, draft: 1, trashed: 2, removed_from_external_system: 3 } enum receive_applications: { email: 0, website: 1 } + enum extension_reason: { no_applications: 0, didnt_find_right_candidate: 1, other_extension_reason: 2 } belongs_to :publisher, optional: true belongs_to :publisher_organisation, class_name: "Organisation", optional: true diff --git a/app/views/publishers/vacancies/extend_deadline/show.html.slim b/app/views/publishers/vacancies/extend_deadline/show.html.slim index fb1f24295a..7b308f25b2 100644 --- a/app/views/publishers/vacancies/extend_deadline/show.html.slim +++ b/app/views/publishers/vacancies/extend_deadline/show.html.slim @@ -45,6 +45,14 @@ hint: -> { "For example 'Easter term'" }, data: { "form-target": "inputText" } + = f.govuk_radio_buttons_fieldset :extension_reason, legend: { text: t(".extension_reason.label") } do + = f.govuk_radio_button :extension_reason, :no_applications, link_errors: true, label: { text: t(".extension_reason.no_applications") } + = f.govuk_radio_button :extension_reason, :didnt_find_right_candidate, link_errors: true, label: { text: t(".extension_reason.didnt_find_right_candidate") } + = f.govuk_radio_button :extension_reason, :other_extension_reason, label: { text: t(".extension_reason.other_extension_reason") } do + = f.govuk_text_area :other_extension_reason_details, + label: { text: t(".extension_reason.other_details") }, + rows: 5 + = f.govuk_submit t("buttons.extend_closing_date"), class: "govuk-!-margin-bottom-5" = govuk_link_to(t("buttons.cancel"), organisation_jobs_with_type_path, class: "govuk-link--no-visited-state govuk-!-font-size-19") diff --git a/config/analytics.yml b/config/analytics.yml index 681d21c1fb..a8c5311ba6 100644 --- a/config/analytics.yml +++ b/config/analytics.yml @@ -414,6 +414,8 @@ shared: - is_job_share - hourly_rate - flexi_working + - extension_reason + - other_extension_reason_details failed_imported_vacancies: - id - import_errors diff --git a/config/locales/activerecord.yml b/config/locales/activerecord.yml index 0e2bf818f3..fafe43d4f1 100644 --- a/config/locales/activerecord.yml +++ b/config/locales/activerecord.yml @@ -234,6 +234,8 @@ en: invalid: Enter a date in the correct format on_or_after: The date the job starts must be in the future on_or_before: The date the job starts must be less than two years in the future + extension_reason: + inclusion: Select the reason why the job deadline is being extended applying_for_the_job_errors: &applying_for_the_job_errors enable_job_applications: cannot_be_changed_once_listed: >- @@ -731,7 +733,7 @@ en: blank: Enter the year the course or training was awarded jobseekers/account_transfer_form: attributes: - email: + email: blank: Enter your email address invalid: Enter a valid email address in the correct format, like name@example.com jobseekers/request_account_transfer_email_form: diff --git a/config/locales/publishers.yml b/config/locales/publishers.yml index 3d95e3b291..b7376abe08 100644 --- a/config/locales/publishers.yml +++ b/config/locales/publishers.yml @@ -472,6 +472,12 @@ en: past: The previous deadline was heading: Extend closing date title: Extend closing date - %{job_title} + extension_reason: + label: Why are you extending this job? + no_applications: No applications + didnt_find_right_candidate: Didn't find the right candidate + other_extension_reason: Other + other_details: Can you provide more details? (optional) update: success: "The deadline for %{job_title} has been extended" expired_feedbacks: diff --git a/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb b/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb new file mode 100644 index 0000000000..0677220c65 --- /dev/null +++ b/db/migrate/20241002105609_add_extension_reason_to_vacancy.rb @@ -0,0 +1,6 @@ +class AddExtensionReasonToVacancy < ActiveRecord::Migration[7.1] + def change + add_column :vacancies, :extension_reason, :integer + add_column :vacancies, :other_extension_reason_details, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 382186e5d7..d0488c3980 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_09_24_144355) do +ActiveRecord::Schema[7.1].define(version: 2024_10_02_105609) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gist" enable_extension "citext" @@ -683,6 +683,8 @@ t.boolean "is_job_share" t.string "hourly_rate" t.string "flexi_working" + t.integer "extension_reason" + t.string "other_extension_reason_details" t.index ["expires_at"], name: "index_vacancies_on_expires_at" t.index ["external_source", "external_reference"], name: "index_vacancies_on_external_source_and_external_reference" t.index ["geolocation", "expires_at", "publish_on"], name: "index_vacancies_on_geolocation_and_expires_at_and_publish_on", using: :gist diff --git a/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb b/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb index cdf0c6ae33..1f04ee5273 100644 --- a/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb +++ b/spec/form_models/publishers/job_listing/extend_deadline_form_spec.rb @@ -10,6 +10,7 @@ let(:earliest_start_date) { 18.months.from_now } let(:latest_start_date) { 19.months.from_now } let(:other_start_date_details) { nil } + let(:extension_reason) { "no_applications" } let(:params) do { @@ -29,6 +30,7 @@ "latest_start_date(2i)" => latest_start_date.month.to_s, "latest_start_date(3i)" => latest_start_date.day.to_s, other_start_date_details: other_start_date_details, + extension_reason: extension_reason, } end diff --git a/spec/jobs/import_from_vacancy_source_job_spec.rb b/spec/jobs/import_from_vacancy_source_job_spec.rb index 529884dd10..e89d8b92be 100644 --- a/spec/jobs/import_from_vacancy_source_job_spec.rb +++ b/spec/jobs/import_from_vacancy_source_job_spec.rb @@ -116,6 +116,7 @@ def each(...) "earliest_start_date" => nil, "ect_status" => "ect_suitable", "enable_job_applications" => true, + "extension_reason" => nil, "expired_vacancy_feedback_email_sent_at" => nil, "expires_at" => "2023-06-06T09:00:00.000+01:00", "external_advert_url" => "https://example.com/jobs/123", @@ -139,6 +140,7 @@ def each(...) "key_stages" => [], "latest_start_date" => nil, "listed_elsewhere" => nil, + "other_extension_reason_details" => nil, "other_start_date_details" => nil, "parental_leave_cover_contract_duration" => nil, "part_time_details" => nil, diff --git a/spec/requests/publishers/vacancies/extend_deadline_spec.rb b/spec/requests/publishers/vacancies/extend_deadline_spec.rb index e869f17a15..7da3c0ccd5 100644 --- a/spec/requests/publishers/vacancies/extend_deadline_spec.rb +++ b/spec/requests/publishers/vacancies/extend_deadline_spec.rb @@ -51,6 +51,7 @@ "starts_on(2i)" => starts_on.month.to_s, "starts_on(3i)" => starts_on.day.to_s, expiry_time: "9:00", + extension_reason: "no_applications", } end diff --git a/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb b/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb index 82fde827e4..15966c555c 100644 --- a/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb +++ b/spec/system/publishers/publishers_can_extend_a_deadline_spec.rb @@ -2,47 +2,58 @@ RSpec.describe "Publishers can extend a deadline" do let(:organisation) { create(:school) } - let!(:vacancy) { create(:vacancy, :published, organisations: [organisation]) } let(:publisher) { create(:publisher) } let(:expires_at) { vacancy.expires_at + 1.month } + let(:extension_reason) { Faker::Lorem.paragraph } + let!(:vacancy) { create(:vacancy, vacancy_type, organisations: [organisation]) } - before { login_publisher(publisher: publisher, organisation: organisation) } - - it "submits form, renders error, then ends listing early" do - visit organisation_jobs_with_type_path(:published) + before do + login_publisher(publisher: publisher, organisation: organisation) + visit organisation_jobs_with_type_path(vacancy_type) click_on vacancy.job_title click_on I18n.t("publishers.vacancies.show.heading_component.action.extend_closing_date") - click_on I18n.t("buttons.extend_closing_date") + end + after { logout } + + context "when the vacancy has not expired" do + let(:vacancy_type) { :published } + + it "submits form, renders error, then extends" do + choose I18n.t("publishers.vacancies.extend_deadline.show.extension_reason.other_extension_reason"), name: "publishers_job_listing_extend_deadline_form[extension_reason]" + click_on I18n.t("buttons.extend_closing_date") - expect(page).to have_content("There is a problem") + expect(page).to have_content("There is a problem") - fill_in "publishers_job_listing_extend_deadline_form[expires_at(1i)]", with: expires_at.year - fill_in "publishers_job_listing_extend_deadline_form[expires_at(2i)]", with: expires_at.month - fill_in "publishers_job_listing_extend_deadline_form[expires_at(3i)]", with: expires_at.day - choose "9am", name: "publishers_job_listing_extend_deadline_form[expiry_time]" + fill_in "publishers_job_listing_extend_deadline_form[expires_at(1i)]", with: expires_at.year + fill_in "publishers_job_listing_extend_deadline_form[expires_at(2i)]", with: expires_at.month + fill_in "publishers_job_listing_extend_deadline_form[expires_at(3i)]", with: expires_at.day + choose "9am", name: "publishers_job_listing_extend_deadline_form[expiry_time]" - click_on I18n.t("buttons.extend_closing_date") + fill_in "publishers_job_listing_extend_deadline_form[other_extension_reason_details]", with: extension_reason - expect(current_path).to eq(organisation_jobs_with_type_path(:published)) + click_on I18n.t("buttons.extend_closing_date") + + expect(current_path).to eq(organisation_jobs_with_type_path(:published)) + + expect(vacancy.reload).to have_attributes(extension_reason: "other_extension_reason", other_extension_reason_details: extension_reason, expires_at: expires_at) + end end context "when the vacancy has expired" do - let!(:expired_vacancy) { create(:vacancy, :expired, organisations: [organisation]) } - - before { visit organisation_jobs_with_type_path(:expired) } + let(:vacancy_type) { :expired } scenario "the closing date can be extended" do - click_on expired_vacancy.job_title - click_on I18n.t("publishers.vacancies.show.heading_component.action.extend_closing_date") - fill_in "publishers_job_listing_extend_deadline_form[expires_at(1i)]", with: expires_at.year fill_in "publishers_job_listing_extend_deadline_form[expires_at(2i)]", with: expires_at.month fill_in "publishers_job_listing_extend_deadline_form[expires_at(3i)]", with: expires_at.day choose "9am", name: "publishers_job_listing_extend_deadline_form[expiry_time]" + choose I18n.t("publishers.vacancies.extend_deadline.show.extension_reason.didnt_find_right_candidate") + click_on I18n.t("buttons.extend_closing_date") expect(current_path).to eq(organisation_jobs_with_type_path(:published)) + expect(vacancy.reload).to have_attributes(extension_reason: "didnt_find_right_candidate", expires_at: expires_at) end end end