diff --git a/Gemfile.lock b/Gemfile.lock
index 7dd945071..4bcfa6266 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -82,7 +82,7 @@ GEM
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2)
aws-eventstream (1.2.0)
- aws-partitions (1.608.0)
+ aws-partitions (1.609.0)
aws-sdk-core (3.131.3)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
@@ -157,7 +157,7 @@ GEM
rubocop
smart_properties
erubi (1.10.0)
- excon (0.92.3)
+ excon (0.92.4)
factory_bot (6.2.1)
activesupport (>= 5.0.0)
factory_bot_rails (6.2.0)
@@ -175,7 +175,7 @@ GEM
pagy (~> 5.10.1)
railties (>= 6.1)
view_component (~> 2.56.2)
- govuk_design_system_formbuilder (3.1.0)
+ govuk_design_system_formbuilder (3.1.1)
actionview (>= 6.1)
activemodel (>= 6.1)
activesupport (>= 6.1)
@@ -225,11 +225,11 @@ GEM
net-protocol
timeout
nio4r (2.5.8)
- nokogiri (1.13.7-arm64-darwin)
+ nokogiri (1.13.8-arm64-darwin)
racc (~> 1.4)
- nokogiri (1.13.7-x86_64-darwin)
+ nokogiri (1.13.8-x86_64-darwin)
racc (~> 1.4)
- nokogiri (1.13.7-x86_64-linux)
+ nokogiri (1.13.8-x86_64-linux)
racc (~> 1.4)
notifications-ruby-client (5.3.0)
jwt (>= 1.5, < 3)
diff --git a/app/controllers/content_controller.rb b/app/controllers/content_controller.rb
index a3e1b4916..c4780a38c 100644
--- a/app/controllers/content_controller.rb
+++ b/app/controllers/content_controller.rb
@@ -1,6 +1,6 @@
class ContentController < ApplicationController
def accessibility_statement
- render_content_page :accessibility_statement
+ render_content_page :accessibility_statement, page_title: "Accessibility statement for Submit social housing lettings and sales data (CORE)"
end
def privacy_notice
diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb
index 6ac482fef..46aceb650 100644
--- a/app/controllers/locations_controller.rb
+++ b/app/controllers/locations_controller.rb
@@ -6,9 +6,12 @@ class LocationsController < ApplicationController
before_action :find_scheme
before_action :authenticate_action!
+ include Modules::SearchFilter
+
def index
- @pagy, @locations = pagy(@scheme.locations)
+ @pagy, @locations = pagy(filtered_collection(@scheme.locations, search_term))
@total_count = @scheme.locations.size
+ @searched = search_term.presence
end
def new
@@ -19,7 +22,12 @@ class LocationsController < ApplicationController
if date_params_missing?(location_params) || valid_date_params?(location_params)
@location = Location.new(location_params)
if @location.save
- location_params[:add_another_location] == "Yes" ? redirect_to(new_location_path(id: @scheme.id)) : redirect_to(scheme_check_answers_path(scheme_id: @scheme.id))
+ if location_params[:add_another_location] == "Yes"
+ redirect_to new_location_path(@scheme)
+ else
+ check_answers_path = @scheme.confirmed? ? scheme_check_answers_path(@scheme, anchor: "locations") : scheme_check_answers_path(@scheme)
+ redirect_to check_answers_path
+ end
else
render :new, status: :unprocessable_entity
end
@@ -92,4 +100,8 @@ private
required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode]
required_params
end
+
+ def search_term
+ params["search"]
+ end
end
diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb
index 44c5ab869..2bae8ae94 100644
--- a/app/controllers/schemes_controller.rb
+++ b/app/controllers/schemes_controller.rb
@@ -47,7 +47,6 @@ class SchemesController < ApplicationController
page = params[:scheme][:page]
validation_errors scheme_params
-
if @scheme.errors.empty? && @scheme.update(scheme_params)
if check_answers
if confirm_secondary_page? page
@@ -104,6 +103,10 @@ private
@scheme.errors.add(key.to_sym)
end
end
+
+ if @scheme.arrangement_type_same? && arrangement_type_value(scheme_params[:arrangement_type]) != "D"
+ @scheme.errors.delete(:managing_organisation_id)
+ end
end
def confirm_secondary_page?(page)
@@ -125,6 +128,8 @@ private
"schemes/details"
elsif page.include?("edit")
"schemes/edit_name"
+ elsif page.include?("check-answers")
+ "schemes/check_answers"
end
end
@@ -150,6 +155,8 @@ private
end
when "edit-name"
scheme_path(@scheme)
+ when "check-answers"
+ schemes_path(scheme_id: @scheme.id)
end
end
@@ -166,16 +173,35 @@ private
:secondary_client_group,
:support_type,
:arrangement_type,
- :intended_stay)
+ :intended_stay,
+ :confirmed)
- full_params = required_params[:arrangement_type] == "D" && required_params[:owning_organisation_id].present? ? required_params.merge(managing_organisation_id: required_params[:owning_organisation_id]) : required_params
+ if arrangement_type_changed_to_different_org?(required_params)
+ required_params[:managing_organisation_id] = nil
+ end
+
+ if arrangement_type_set_to_same_org?(required_params)
+ required_params[:managing_organisation_id] = required_params[:owning_organisation_id] || @scheme.owning_organisation_id
+ end
- full_params[:sensitive] = full_params[:sensitive].to_i if full_params[:sensitive]
+ required_params[:sensitive] = required_params[:sensitive].to_i if required_params[:sensitive]
if current_user.data_coordinator?
- full_params[:owning_organisation_id] = current_user.organisation_id
+ required_params[:owning_organisation_id] = current_user.organisation_id
end
- full_params
+ required_params
+ end
+
+ def arrangement_type_set_to_same_org?(required_params)
+ arrangement_type_value(required_params[:arrangement_type]) == "D" || (required_params[:arrangement_type].blank? && @scheme.present? && @scheme.arrangement_type_same?)
+ end
+
+ def arrangement_type_changed_to_different_org?(required_params)
+ @scheme.present? && @scheme.arrangement_type_same? && arrangement_type_value(required_params[:arrangement_type]) != "D" && required_params[:managing_organisation_id].blank?
+ end
+
+ def arrangement_type_value(key)
+ key.present? ? Scheme::ARRANGEMENT_TYPE[key.to_sym] : nil
end
def search_term
diff --git a/app/frontend/controllers/accessible_autocomplete_controller.js b/app/frontend/controllers/accessible_autocomplete_controller.js
index 812cd37d3..3e19c4c9e 100644
--- a/app/frontend/controllers/accessible_autocomplete_controller.js
+++ b/app/frontend/controllers/accessible_autocomplete_controller.js
@@ -6,7 +6,7 @@ import { enhanceOption, suggestion, sort } from '../modules/search'
export default class extends Controller {
connect () {
const selectEl = this.element
- const selectOptions = Array.from(selectEl.options)
+ const selectOptions = Array.from(selectEl.options).filter(function (option, index, arr) { return option.value !== '' })
const options = selectOptions.map((o) => enhanceOption(o))
const matches = /^(\w+)\[(\w+)\]$/.exec(selectEl.name)
diff --git a/app/frontend/styles/_errors.scss b/app/frontend/styles/_errors.scss
new file mode 100644
index 000000000..5883fd416
--- /dev/null
+++ b/app/frontend/styles/_errors.scss
@@ -0,0 +1,4 @@
+.app-summary-list__value--error {
+ border-left: $govuk-border-width solid $govuk-error-colour;
+ padding-left: govuk-spacing(3);
+}
diff --git a/app/frontend/styles/application.scss b/app/frontend/styles/application.scss
index dd4dc3b97..4b26044d1 100644
--- a/app/frontend/styles/application.scss
+++ b/app/frontend/styles/application.scss
@@ -40,6 +40,7 @@ $govuk-breakpoints: (
@import "primary-navigation";
@import "search";
@import "sub-navigation";
+@import "errors";
// App utilities
.app-\!-colour-muted {
diff --git a/app/helpers/details_table_helper.rb b/app/helpers/details_table_helper.rb
index c39bf75d7..9d7c16f22 100644
--- a/app/helpers/details_table_helper.rb
+++ b/app/helpers/details_table_helper.rb
@@ -4,7 +4,7 @@ module DetailsTableHelper
list = attribute[:value].map { |value| "
#{value}" }.join
simple_format(list, { class: "govuk-list govuk-list--bullet" }, wrapper_tag: "ul")
else
- value = attribute[:value].is_a?(Array) ? attribute[:value].first : attribute[:value] || "None"
+ value = attribute[:value].is_a?(Array) ? attribute[:value].first : attribute[:value] || "You didn’t answer this question".html_safe
simple_format(value.to_s, { class: "govuk-body" }, wrapper_tag: "p")
end
diff --git a/app/helpers/tab_nav_helper.rb b/app/helpers/tab_nav_helper.rb
index 4dc015763..68caf16c1 100644
--- a/app/helpers/tab_nav_helper.rb
+++ b/app/helpers/tab_nav_helper.rb
@@ -14,7 +14,8 @@ module TabNavHelper
def scheme_cell(scheme)
link_text = scheme.service_name
- [govuk_link_to(link_text, scheme), "Scheme #{scheme.primary_client_group}"].join("\n")
+ link = scheme.confirmed? ? scheme : scheme_check_answers_path(scheme)
+ [govuk_link_to(link_text, link), "Scheme #{scheme.primary_client_group}"].join("\n")
end
def org_cell(user)
diff --git a/app/models/case_log.rb b/app/models/case_log.rb
index fdb4972c9..269d3edd8 100644
--- a/app/models/case_log.rb
+++ b/app/models/case_log.rb
@@ -413,7 +413,7 @@ class CaseLog < ApplicationRecord
csv << attribute_names + %w[unittype_sh]
all.find_each do |record|
- csv << record.attributes.merge({ "unittype_sh" => record.unittype_sh }).map do |att, val|
+ csv << record.attributes.merge({ "unittype_sh" => record.unittype_sh, "la" => record.la }).map do |att, val|
record.form.get_question(att, record)&.label_from_value(val) || val
end
end
@@ -538,10 +538,17 @@ private
self.created_by = nil if created_by.organisation != owning_organisation
end
+ def reset_scheme
+ return unless scheme && owning_organisation
+
+ self.scheme = nil if scheme.owning_organisation != owning_organisation
+ end
+
def reset_invalidated_dependent_fields!
return unless form
reset_created_by
+ reset_scheme
reset_not_routed_questions
reset_derived_questions
end
@@ -602,7 +609,8 @@ private
end
def get_inferred_la(postcode)
- PIO.infer_la(postcode)
+ result = PIO.lookup(postcode)
+ result[:location_code] if result
end
def get_has_benefits
@@ -610,9 +618,9 @@ private
end
def get_lettype
- return unless renttype.present? && needstype.present? && owning_organisation.present? && owning_organisation[:provider_type].present?
+ return unless rent_type.present? && needstype.present? && owning_organisation.present? && owning_organisation[:provider_type].present?
- case RENT_TYPE_MAPPING_LABELS[renttype]
+ case RENT_TYPE_MAPPING_LABELS[RENT_TYPE_MAPPING[rent_type]]
when "Social Rent"
if is_supported_housing?
owning_organisation[:provider_type] == "PRP" ? 2 : 4
diff --git a/app/models/form.rb b/app/models/form.rb
index 57b529f10..b493c25c2 100644
--- a/app/models/form.rb
+++ b/app/models/form.rb
@@ -79,7 +79,7 @@ class Form
when :in_progress
"#{next_subsection.id}/check_answers".dasherize
when :not_started
- first_question_in_subsection = next_subsection.pages.first.id
+ first_question_in_subsection = next_subsection.pages.find { |page| page.routed_to?(case_log, nil) }.id
first_question_in_subsection.to_s.dasherize
else
"error"
diff --git a/app/models/form/question.rb b/app/models/form/question.rb
index 41a79fd3a..eb437b456 100644
--- a/app/models/form/question.rb
+++ b/app/models/form/question.rb
@@ -51,16 +51,20 @@ class Form::Question
def get_inferred_answers(case_log)
return [] unless inferred_answers
- enabled_inferred_answers(inferred_answers, case_log).keys.map do |x|
- question = form.get_question(x, case_log)
+ enabled_inferred_answers(inferred_answers, case_log).keys.map do |question_id|
+ question = form.get_question(question_id, case_log)
if question.present?
- question.label_from_value(case_log[x])
+ question.label_from_value(case_log[question_id])
else
- Array(x.to_s.split(".")).inject(case_log) { |o, a| o.present? ? o.public_send(*a) : "" }
+ Array(question_id.to_s.split(".")).inject(case_log) { |log, method| log.present? ? log.public_send(*method) : "" }
end
end
end
+ def get_extra_check_answer_value(_case_log)
+ nil
+ end
+
def read_only?
!!readonly
end
diff --git a/app/models/form/setup/questions/created_by_id.rb b/app/models/form/setup/questions/created_by_id.rb
index eee7d9485..f32163a0f 100644
--- a/app/models/form/setup/questions/created_by_id.rb
+++ b/app/models/form/setup/questions/created_by_id.rb
@@ -13,8 +13,9 @@ class Form::Setup::Questions::CreatedById < ::Form::Question
answer_opts = { "" => "Select an option" }
return answer_opts unless ActiveRecord::Base.connected?
- User.select(:id, :name).each_with_object(answer_opts) do |user, hsh|
- hsh[user.id] = user.name
+ User.select(:id, :name, :email).each_with_object(answer_opts) do |user, hsh|
+ hsh[user.id] = user.name if user.name.present?
+ hsh[user.id] = user.email if user.name.blank?
hsh
end
end
diff --git a/app/models/form/setup/questions/location_id.rb b/app/models/form/setup/questions/location_id.rb
index d0650f9ea..1fa8e82e2 100644
--- a/app/models/form/setup/questions/location_id.rb
+++ b/app/models/form/setup/questions/location_id.rb
@@ -34,6 +34,10 @@ class Form::Setup::Questions::LocationId < ::Form::Question
!supported_housing_selected?(case_log)
end
+ def get_extra_check_answer_value(case_log)
+ case_log.form.get_question("la", nil).label_from_value(case_log.la)
+ end
+
private
def supported_housing_selected?(case_log)
diff --git a/app/models/form/setup/questions/scheme_id.rb b/app/models/form/setup/questions/scheme_id.rb
index fe811f28a..27a9a6664 100644
--- a/app/models/form/setup/questions/scheme_id.rb
+++ b/app/models/form/setup/questions/scheme_id.rb
@@ -20,11 +20,11 @@ class Form::Setup::Questions::SchemeId < ::Form::Question
end
def displayed_answer_options(case_log)
- return {} unless case_log.created_by
-
- user_org_scheme_ids = Scheme.select(:id).where(owning_organisation_id: case_log.created_by.organisation_id).joins(:locations).merge(Location.where("startdate <= ? or startdate IS NULL", Time.zone.today)).map(&:id)
+ organisation = case_log.owning_organisation || case_log.created_by&.organisation
+ schemes = organisation ? Scheme.select(:id).where(owning_organisation_id: organisation.id, confirmed: true) : Scheme.select(:id).where(confirmed: true)
+ filtered_scheme_ids = schemes.joins(:locations).merge(Location.where("startdate <= ? or startdate IS NULL", Time.zone.today)).map(&:id)
answer_options.select do |k, _v|
- user_org_scheme_ids.include?(k.to_i) || k.blank?
+ filtered_scheme_ids.include?(k.to_i) || k.blank?
end
end
diff --git a/app/models/location.rb b/app/models/location.rb
index 4812e2cd5..c21917b70 100644
--- a/app/models/location.rb
+++ b/app/models/location.rb
@@ -3,10 +3,14 @@ class Location < ApplicationRecord
validates :units, :type_of_unit, :mobility_type, presence: true
belongs_to :scheme
- before_save :infer_la!, if: :postcode_changed?
+ before_save :lookup_postcode!, if: :postcode_changed?
attr_accessor :add_another_location
+ scope :search_by_postcode, ->(postcode) { where("postcode ILIKE ?", "%#{postcode.gsub(/\s+/, '')}%") }
+ scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") }
+ scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) }
+
MOBILITY_TYPE = {
"Wheelchair-user standard": "W",
"Fitted with equipment and adaptations": "A",
@@ -48,7 +52,11 @@ private
end
end
- def infer_la!
- self.location_code = PIO.infer_la(postcode)
+ def lookup_postcode!
+ result = PIO.lookup(postcode)
+ if result
+ self.location_code = result[:location_code]
+ self.location_admin_district = result[:location_admin_district]
+ end
end
end
diff --git a/app/models/scheme.rb b/app/models/scheme.rb
index 901481966..5ac48b310 100644
--- a/app/models/scheme.rb
+++ b/app/models/scheme.rb
@@ -6,9 +6,11 @@ class Scheme < ApplicationRecord
scope :filter_by_id, ->(id) { where(id: (id.start_with?("S") ? id[1..] : id)) }
scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") }
- scope :search_by_postcode, ->(postcode) { joins(:locations).where("locations.postcode ILIKE ?", "%#{postcode.delete(' ')}%") }
+ scope :search_by_postcode, ->(postcode) { joins("LEFT JOIN locations ON locations.scheme_id = schemes.id").where("locations.postcode ILIKE ?", "%#{postcode.delete(' ')}%") }
scope :search_by, ->(param) { search_by_postcode(param).or(search_by_service_name(param)).or(filter_by_id(param)).distinct }
+ validate :validate_confirmed
+
SENSITIVE = {
No: 0,
Yes: 1,
@@ -100,49 +102,49 @@ class Scheme < ApplicationRecord
def check_details_attributes
[
- { name: "Service code", value: id_to_display },
- { name: "Name", value: service_name },
- { name: "Confidential information", value: sensitive },
- { name: "Type of scheme", value: scheme_type },
- { name: "Registered under Care Standards Act 2000", value: registered_under_care_act },
- { name: "Housing stock owned by", value: owning_organisation.name },
- { name: "Support services provided by", value: arrangement_type },
+ { name: "Service code", value: id_to_display, id: "id" },
+ { name: "Name", value: service_name, id: "service_name" },
+ { name: "Confidential information", value: sensitive, id: "sensitive" },
+ { name: "Type of scheme", value: scheme_type, id: "scheme_type" },
+ { name: "Registered under Care Standards Act 2000", value: registered_under_care_act, id: "registered_under_care_act" },
+ { name: "Housing stock owned by", value: owning_organisation.name, id: "owning_organisation_id" },
+ { name: "Support services provided by", value: arrangement_type, id: "arrangement_type" },
]
end
def check_support_services_provider_attributes
[
- { name: "Organisation providing support", value: managing_organisation&.name },
+ { name: "Organisation providing support", value: managing_organisation&.name, id: "managing_organisation_id" },
]
end
def check_primary_client_attributes
[
- { name: "Primary client group", value: primary_client_group },
+ { name: "Primary client group", value: primary_client_group, id: "primary_client_group" },
]
end
def check_secondary_client_confirmation_attributes
[
- { name: "Has another client group", value: has_other_client_group },
+ { name: "Has another client group", value: has_other_client_group, id: "has_other_client_group" },
]
end
def check_secondary_client_attributes
[
- { name: "Secondary client group", value: secondary_client_group },
+ { name: "Secondary client group", value: secondary_client_group, id: "secondary_client_group" },
]
end
def check_support_attributes
[
- { name: "Level of support given", value: support_type },
- { name: "Intended length of stay", value: intended_stay },
+ { name: "Level of support given", value: support_type, id: "support_type" },
+ { name: "Intended length of stay", value: intended_stay, id: "intended_stay" },
]
end
def display_attributes
- [
+ base_attributes = [
{ name: "Scheme code", value: id_to_display },
{ name: "Name", value: service_name, edit: true },
{ name: "Confidential information", value: sensitive, edit: true },
@@ -157,6 +159,11 @@ class Scheme < ApplicationRecord
{ name: "Level of support given", value: support_type },
{ name: "Intended length of stay", value: intended_stay },
]
+
+ if arrangement_type_same?
+ base_attributes.delete({ name: "Organisation providing support", value: managing_organisation&.name })
+ end
+ base_attributes
end
def synonyms
@@ -196,4 +203,22 @@ class Scheme < ApplicationRecord
}
Scheme.intended_stays.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize, description: hints[key.to_sym]) }
end
+
+ def arrangement_type_same?
+ arrangement_type.present? && ARRANGEMENT_TYPE[arrangement_type.to_sym] == "D"
+ end
+
+ def validate_confirmed
+ required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units has_other_client_group]
+
+ if confirmed == true
+ required_attributes.any? do |attribute|
+ if self[attribute].blank?
+ errors.add :base
+ errors.add attribute.to_sym
+ self.confirmed = false
+ end
+ end
+ end
+ end
end
diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb
index c86b43974..686c69174 100644
--- a/app/models/validations/soft_validations.rb
+++ b/app/models/validations/soft_validations.rb
@@ -28,14 +28,14 @@ module Validations::SoftValidations
def rent_in_soft_min_range?
return unless brent && weekly_value(brent) && startdate
- rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype:)
+ rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype: get_lettype)
rent_range.present? && weekly_value(brent).between?(rent_range.hard_min, rent_range.soft_min)
end
def rent_in_soft_max_range?
return unless brent && weekly_value(brent) && startdate
- rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype:)
+ rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype: get_lettype)
rent_range.present? && weekly_value(brent).between?(rent_range.soft_max, rent_range.hard_max)
end
diff --git a/app/services/postcode_service.rb b/app/services/postcode_service.rb
index a82dcc2aa..74c1f4895 100644
--- a/app/services/postcode_service.rb
+++ b/app/services/postcode_service.rb
@@ -3,7 +3,7 @@ class PostcodeService
@pio = Postcodes::IO.new
end
- def infer_la(postcode)
+ def lookup(postcode)
# Avoid network calls when postcode is invalid
return unless postcode.match(POSTCODE_REGEXP)
@@ -16,7 +16,10 @@ class PostcodeService
Rails.logger.warn("Postcodes.io lookup timed out")
end
if postcode_lookup && postcode_lookup.info.present?
- postcode_lookup.codes["admin_district"]
+ {
+ location_code: postcode_lookup.codes["admin_district"],
+ location_admin_district: postcode_lookup&.admin_district,
+ }
end
end
diff --git a/app/views/content/accessibility_statement.md b/app/views/content/accessibility_statement.md
index e69de29bb..027a641e0 100644
--- a/app/views/content/accessibility_statement.md
+++ b/app/views/content/accessibility_statement.md
@@ -0,0 +1,61 @@
+This accessibility statement applies to the Submit social housing lettings and sales data (CORE) online service.
+
+This website is run by the Department for Levelling Up, Housing and Communities (DLUHC). We want as many people as possible to be able to use this website. For example, that means you should be able to:
+
+- change colours, contrast levels and fonts
+- zoom in up to 300% without the text spilling off the screen
+- navigate most of the website using just a keyboard
+- navigate most of the website using speech recognition software
+- listen to most of the website using a screen reader (including the most recent versions of JAWS, NVDA and VoiceOver)
+
+We’ve also made the website text as simple as possible to understand.
+
+AbilityNet has advice on making your device easier to use if you have a disability.
+
+### How accessible this website is
+
+We know some parts of this website are not fully accessible:
+
+- an empty link on the ‘Users’ page within ‘Your Organisation’ will cause problems for some users of assistive technology (A)
+- an optional field is not clearly labelled on the ‘Invite user to submit CORE data’ page (A)
+- a skip link for an error message on the ‘Household’s combined income after tax’ page doesn’t work (A)
+- radio buttons on multiple pages had different functionality depending on the browser used (AAA)
+- the required currency symbol on the ‘Household’s combined income after tax’ page is hidden from the label for users of screen readers (AAA)
+- the input type ‘email’ interferes with Dragon voice activation software on the ‘Sign in to your account to submit CORE data page’ (AAA)
+
+### Feedback and contact information
+
+If you need information on this website in a different format like accessible PDF, large print, easy read, audio recording or braille, you can contact us by:
+
+- email: [dluhc.digital-services@levellingup.gov.uk](mailto: dluhc.digital-services@levellingup.gov.uk)
+- phone: 0333 202 5084
+
+We’ll consider your request and get back to you in 2 working days.
+
+You can also contact us through the helpdesk.
+
+### Reporting accessibility problems with this website
+
+We’re always looking to improve the accessibility of this website. If you find any problems not listed on this page or think we’re not meeting accessibility requirements, contact the helpdesk.
+
+### Enforcement procedure
+
+The Equality and Human Rights Commission (EHRC) is responsible for enforcing the Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018 (the ‘accessibility regulations’). If you’re not happy with how we respond to your complaint, contact the Equality Advisory and Support Service (EASS).
+
+## Technical information about this website’s accessibility
+
+DLUHC is committed to making its website accessible, in accordance with the Public Sector Bodies (Websites and Mobile Applications) (No. 2) Accessibility Regulations 2018.
+
+### Compliance status
+
+This website is partially compliant with the Web Content Accessibility Guidelines version 2.1 AA standard due to the non-compliances listed below.
+
+## Non-accessible content
+
+The content listed below is non-accessible for the following reasons.
+
+### Non-compliance with the accessibility regulations
+
+An empty link on the ‘Users’ page within ‘Your Organisation’ will cause problems for some users of assistive technology. This fails WCAG 2.1 success criteria 2.4.4 Link Purpose – in context (Level A) and 3.3.2 Labels or Instructions (Level A).
+
+We plan to fix this by December 2022.
diff --git a/app/views/form/_check_answers_summary_list.html.erb b/app/views/form/_check_answers_summary_list.html.erb
index 6b7761437..d04dfa031 100644
--- a/app/views/form/_check_answers_summary_list.html.erb
+++ b/app/views/form/_check_answers_summary_list.html.erb
@@ -3,7 +3,12 @@
<% summary_list.row do |row| %>
<% row.key { question.check_answer_label.to_s.presence || question.header.to_s } %>
<% row.value do %>
- <%= get_answer_label(question, @case_log) %>
+ <%= get_answer_label(question, @case_log) %>
+ <% extra_value = question.get_extra_check_answer_value(@case_log) %>
+ <% if extra_value %>
+ <%= extra_value %>
+ <% end %>
+
<% question.get_inferred_answers(@case_log).each do |inferred_answer| %>
<%= inferred_answer %>
<% end %>
diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb
index 91cff0282..7694b5ca8 100644
--- a/app/views/layouts/_footer.html.erb
+++ b/app/views/layouts/_footer.html.erb
@@ -31,6 +31,9 @@
Helpful links