Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing support functionality to grant an editable extension to any non editable section #8722

Merged
merged 14 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/components/support_interface/application_summary_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def rows
previous_application_row,
subsequent_application_row,
average_distance_row,
editable_until_row,
].compact
end

Expand Down Expand Up @@ -119,6 +120,17 @@ def average_distance_row
}
end

def editable_until_row
{
key: 'Editable until',
value: application_form.editable_until? ? application_form.editable_until.to_fs(:govuk_date_and_time) : nil,
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved
action: {
href: support_interface_editable_until_path(application_form),
visually_hidden_text: 'editable until',
},
}
end

def formatted_status
candidate_flow_state = ApplicationFormStateInferrer.new(application_form).state
name = I18n.t!("candidate_flow_application_states.#{candidate_flow_state}.name")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module SupportInterface
module ApplicationForms
class EditableUntilController < SupportInterfaceController
def edit
@application_form = ApplicationForm.find(params[:application_form_id])
@form = EditableUntilForm.new(application_form: @application_form)
end

def update
@application_form = ApplicationForm.find(params[:application_form_id])
@form = EditableUntilForm.new(editable_until_params.merge(application_form: @application_form))

if @form.save
flash[:success] = 'Application form updated'
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved
redirect_to support_interface_application_form_path(@application_form)
else
render :edit
end
end

private

def editable_until_params
params.require(:support_interface_editable_until_form).permit!
end
end
end
end
54 changes: 54 additions & 0 deletions app/forms/support_interface/editable_until_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module SupportInterface
class EditableUntilForm
include ActiveModel::Model
attr_accessor :application_form, :audit_comment, :audit_comment_description
attr_writer :sections, :editable_until

validates :audit_comment, presence: true
validates_with ZendeskUrlValidator
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved

def non_editable_sections
Section.non_editable.insert(2, science_gcse).flatten.compact
end

def science_gcse
Section.all.find { |section| section.id == :science_gcse }
end

def sections
Array(current_editable_sections).compact_blank.map(&:to_sym)
end

def save
return false unless valid?

@application_form.update!(
editable_sections:,
editable_until:,
audit_comment: full_audit,
)
end

def editable_sections
@sections.compact_blank
end

def editable_until
Rails.configuration.x.sections.editable_window.business_days.from_now.end_of_day if editable_sections.present?
end

def full_audit
return "#{audit_comment} - #{audit_comment_description}" if audit_comment_description.present?

audit_comment
end

private

def current_editable_sections
return @sections if @sections.present?

@application_form.editable_sections if @application_form.editable_until? && Time.zone.now < @application_form.editable_until
end
end
end
7 changes: 7 additions & 0 deletions app/models/application_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,13 @@ def by_section(*sections)
module_function :by_column, :by_section
end

def granted_editable_extension?(section_id)
editable_sections? &&
editable_until? &&
Time.zone.now < editable_until &&
Array(editable_sections).map(&:to_sym).include?(section_id)
end

private

def geocode_address_and_update_region_if_required
Expand Down
22 changes: 0 additions & 22 deletions app/services/candidate_interface/section.rb

This file was deleted.

46 changes: 25 additions & 21 deletions app/services/candidate_interface/section_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,11 @@ def initialize(current_application:, controller_path:, action_name:, params:)
@params = params
end

def self.editable_sections
[
Section.new(controller: 'CandidateInterface::PersonalDetails'),
Section.new(controller: 'CandidateInterface::ContactDetails'),
Section.new(controller: 'CandidateInterface::TrainingWithADisability'),
Section.new(controller: 'CandidateInterface::InterviewAvailability'),
Section.new(controller: 'CandidateInterface::EqualityAndDiversity'),
Section.new(controller: 'CandidateInterface::PersonalStatement'),
Section.new(
controller: 'CandidateInterface::Gcse',
condition: ->(section, policy) { section.science_gcse?(policy) },
),
Section.new(controller: 'CandidateInterface::EnglishForeignLanguage'),
]
end

def can_edit?
any_offer_accepted? || all_applications_unsubmitted? || editable_section?
any_offer_accepted? ||
all_applications_unsubmitted? ||
editable_section? ||
granted_editable_extension?
end

def personal_statement?
Expand All @@ -42,15 +29,32 @@ def all_applications_unsubmitted?
end

def editable_section?
self.class.editable_sections.any? do |section|
controller_match = @controller_path.classify =~ /#{section.controller}/
Section.editable.any? do |section|
controller_match = section_match_with_controller(section)

if controller_match.present? && section.condition.present?
section.condition.call(section, self)
if controller_match.present? && section.editable_condition.present?
section.editable_condition.call(section, self)
else
controller_match
end
end
end

def granted_editable_extension?
Section.all.any? do |section|
controller_match = section_match_with_controller(section)
next unless controller_match.present? && current_application.granted_editable_extension?(section.id)

if section.editable_condition.present?
section.editable_condition.call(section, self)
else
controller_match
end
end
end

def section_match_with_controller(section)
@controller_path.classify =~ /#{section.controller}/
end
end
end
86 changes: 86 additions & 0 deletions app/services/section.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class Section
attr_accessor :id, :controller, :editable_condition

def initialize(identifier, controller:, editable_condition: nil)
@id = identifier
@controller = controller
@editable_condition = editable_condition
end

def name
I18n.t("sections.#{id}")
end

def science_gcse?(policy)
params = policy.params
current_application = policy.current_application
subject = params[:subject]

((subject && subject == 'science') || policy.controller_path.include?('candidate_interface/gcse/science')) &&
(current_application.granted_editable_extension?(:science_gcse) ||
current_application
.application_choices
.select(&:science_gcse_needed?)
.all?(&:unsubmitted?)
)
end

def maths_gcse?(policy)
params = policy.params
subject = params[:subject]

(subject && subject == 'maths') || policy.controller_path.include?('candidate_interface/gcse/maths')
end

def english_gcse?(policy)
params = policy.params
subject = params[:subject]

(subject && subject == 'english') || policy.controller_path.include?('candidate_interface/gcse/english')
end

def eql?(other)
id == other.id
end

def self.all
[
Section.new(:personal_details, controller: 'CandidateInterface::PersonalDetails'),
Section.new(:contact_details, controller: 'CandidateInterface::ContactDetails'),
Section.new(:training_with_a_disability, controller: 'CandidateInterface::TrainingWithADisability'),
Section.new(:interview_preferences, controller: 'CandidateInterface::InterviewAvailability'),
Section.new(:equality_and_diversity, controller: 'CandidateInterface::EqualityAndDiversity'),
Section.new(:becoming_a_teacher, controller: 'CandidateInterface::PersonalStatement'),
Section.new(
:english_gcse,
controller: 'CandidateInterface::Gcse',
editable_condition: ->(section, policy) { section.english_gcse?(policy) },
),
Section.new(
:maths_gcse,
controller: 'CandidateInterface::Gcse',
editable_condition: ->(section, policy) { section.maths_gcse?(policy) },
),
Section.new(
:science_gcse,
controller: 'CandidateInterface::Gcse',
editable_condition: ->(section, policy) { section.science_gcse?(policy) },
),
Section.new(:efl, controller: 'CandidateInterface::EnglishForeignLanguage'),
Section.new(:other_qualifications, controller: 'CandidateInterface::OtherQualifications'),
Section.new(:degrees, controller: 'CandidateInterface::Degrees'),
Section.new(:work_history, controller: 'CandidateInterface::RestructuredWorkHistory'),
Section.new(:volunteering, controller: 'CandidateInterface::Volunteering'),
Section.new(:references, controller: 'CandidateInterface::References'),
Section.new(:safeguarding_issues, controller: 'CandidateInterface::Safeguarding'),
]
end

def self.editable
all.select { |section| section.id.in?(Rails.application.config.x.sections.editable) }
end

def self.non_editable
all.difference(editable)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<% content_for :browser_title, title_with_error_prefix('Update editable until', @form.errors.any?) %>
<% content_for :before_content, govuk_back_link_to(support_interface_application_form_path(@application_form)) %>

<%= form_with model: @form, url: support_interface_editable_until_path(@application_form), method: :post do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= f.govuk_error_summary %>

<h1 class="govuk-heading-l">
Make a candidate’s application editable
</h1>

<%= f.govuk_collection_check_boxes :sections, @form.non_editable_sections, :id, :name, legend: { text: 'Which sections do you want to make editable?' }, hint: { text: 'Select all that apply.' } %>
<%= f.govuk_text_field :audit_comment, label: { text: 'Zendesk ticket', size: 'm' } %>
<%= f.govuk_text_field :audit_comment_description, label: { text: 'Why are you making this application editable? (optional)', size: 'm' }, hint: { text: 'This will appear in the audit log alongside this change.' } %>

<%= f.govuk_submit 'Update' %>
</div>
</div>
<% end %>
12 changes: 12 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,17 @@ class Application < Rails::Application
}

config.action_mailer.deliver_later_queue_name = :mailers

config.x.sections.editable = %i[
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved
personal_details
contact_details
training_with_a_disability
interview_preferences
equality_and_diversity
becoming_a_teacher
science_gcse
efl
]
config.x.sections.editable_window = 5
end
end
18 changes: 18 additions & 0 deletions config/locales/sections.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
en:
sections:
personal_details: Personal details
contact_details: Contact details
training_with_a_disability: Ask for support if you’re disabled
interview_preferences: Interview availability
equality_and_diversity: Equality and diversity
becoming_a_teacher: Personal statement
science_gcse: Science GCSE or equivalent
maths_gcse: Maths GCSE or equivalent
english_gcse: English GCSE or equivalent
efl: English as foreign language
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved
references: References
safeguarding_issues: Safeguarding
other_qualifications: A levels and other qualifications
degrees: Degree
volunteering: Unpaid experience
work_history: Work history
4 changes: 4 additions & 0 deletions config/locales/support_interface/support_interface.yml
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,8 @@ en:
attributes:
audit_comment:
blank: Enter a Zendesk ticket URL
support_interface/editable_until_form:
attributes:
audit_comment:
blank: Add a link to the Zendesk ticket
invalid: Enter a valid Zendesk ticket URL
3 changes: 3 additions & 0 deletions config/routes/support.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
get '/change-course-choice/:application_choice_id' => 'application_forms/courses#edit', as: :application_form_change_course_choice
post '/change-course-choice/:application_choice_id' => 'application_forms/courses#update'

get '/editable-until' => 'application_forms/editable_until#edit'
tomas-stefano marked this conversation as resolved.
Show resolved Hide resolved
post '/editable-until' => 'application_forms/editable_until#update'

get '/audit' => 'application_forms#audit', as: :application_form_audit
get '/comments/new' => 'application_forms/comments#new', as: :application_form_new_comment
post '/comments' => 'application_forms/comments#create', as: :application_form_comments
Expand Down
Loading
Loading