diff --git a/app/helpers/form_page_error_helper.rb b/app/helpers/form_page_error_helper.rb new file mode 100644 index 000000000..f03c53694 --- /dev/null +++ b/app/helpers/form_page_error_helper.rb @@ -0,0 +1,6 @@ +module FormPageErrorHelper + def remove_other_page_errors(case_log, page) + other_page_error_ids = case_log.errors.map(&:attribute) - page.questions.map { |q| q.id.to_sym }.concat([:base]) + other_page_error_ids.each { |id| case_log.errors.delete(id) } + end +end diff --git a/app/models/case_log.rb b/app/models/case_log.rb index e689768ac..898dc44af 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -139,6 +139,7 @@ class CaseLog < ApplicationRecord enum household_charge: POLAR, _suffix: true enum is_carehome: POLAR, _suffix: true enum nocharge: POLAR, _suffix: true + enum referral: REFERRAL, _suffix: true AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze OPTIONAL_FIELDS = %w[postcode_known la_known first_time_property_let_as_social_housing].freeze diff --git a/app/models/constants/case_log.rb b/app/models/constants/case_log.rb index d55c85355..712aff8d0 100644 --- a/app/models/constants/case_log.rb +++ b/app/models/constants/case_log.rb @@ -103,11 +103,11 @@ module Constants::CaseLog }.freeze PREVIOUS_TENANCY = { - "Owner occupation (private) " => 26, + "Owner occupation (private)" => 26, "Owner occupation (low cost home ownership)" => 27, "Private sector tenancy" => 3, "Tied housing or rented with job" => 4, - "Supported housing" => 5, + "Supported housing" => 6, "Sheltered accomodation" => 8, "Residential care home" => 9, "Living with friends or family" => 28, @@ -1095,4 +1095,33 @@ module Constants::CaseLog "No" => 3, "Don’t know" => 4, }.freeze + + REFERRAL = { + "Internal transfer" => 1, + "Tenant applied directly (no referral or nomination)" => 2, + "Private registered provider (PRP) lettings only - nominated by a local housing authority" => 3, + "Private registered provider (PRP) supported lettings only - referred by local authority housing department" => 4, + "Re-located through official housing mobility scheme" => 8, + "Other social landlord" => 10, + "Community learning disability team" => 9, + "Police, probation or prison" => 12, + "Youth offending team" => 13, + "Community mental health team" => 14, + "Health service" => 15, + "Voluntary agency" => 7, + "Other" => 16, + }.freeze + + REFERRAL_INVALID_TMP = ["Re-located through official housing mobility scheme", + "Other social landlord", + "Police, probation or prison", + "Youth offending team", + "Community mental health team", + "Health service"].freeze + + NON_TEMP_ACCOMMODATION = ["Tied housing or rented with job", + "Supported housing", + "Sheltered accomodation", + "Home Office Asylum Support", + "Other"].freeze end diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb index 6d364667d..710332d8c 100644 --- a/app/models/validations/household_validations.rb +++ b/app/models/validations/household_validations.rb @@ -1,4 +1,6 @@ module Validations::HouseholdValidations + include Constants::CaseLog + # Validations methods need to be called 'validate_' to run on model save # or 'validate_' to run on submit as well def validate_reasonable_preference(record) @@ -84,6 +86,12 @@ module Validations::HouseholdValidations end end + def validate_previous_housing_situation(record) + if record.rsnvac == "Relet to tenant who occupied same property as temporary accommodation" && NON_TEMP_ACCOMMODATION.include?(record.prevten) + record.errors.add :prevten, I18n.t("validations.household.prevten.non_temp_accommodation") + end + end + private def women_of_child_bearing_age_in_household(record) diff --git a/app/models/validations/local_authority_validations.rb b/app/models/validations/local_authority_validations.rb index b4b6d8f1c..b241e158e 100644 --- a/app/models/validations/local_authority_validations.rb +++ b/app/models/validations/local_authority_validations.rb @@ -1,4 +1,5 @@ module Validations::LocalAuthorityValidations + include Constants::CaseLog POSTCODE_REGEXP = Validations::PropertyValidations::POSTCODE_REGEXP def validate_previous_accommodation_postcode(record) @@ -8,4 +9,10 @@ module Validations::LocalAuthorityValidations record.errors.add :previous_postcode, error_message end end + + def validate_referral(record) + if record.rsnvac == "Relet to tenant who occupied same property as temporary accommodation" && REFERRAL_INVALID_TMP.include?(record.referral) + record.errors.add :referral, I18n.t("validations.local_authority.referral.rsnvac_non_temp") + end + end end diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index d91ea931f..d564a73a9 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -40,6 +40,14 @@ module Validations::PropertyValidations if record.first_time_property_let_as_social_housing? && record.rsnvac.present? && !FIRST_LET_VACANCY_REASONS.include?(record.rsnvac) record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.first_let_social") end + + if record.rsnvac == "Relet to tenant who occupied same property as temporary accommodation" && NON_TEMP_ACCOMMODATION.include?(record.prevten) + record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.non_temp_accommodation") + end + + if record.rsnvac == "Relet to tenant who occupied same property as temporary accommodation" && REFERRAL_INVALID_TMP.include?(record.referral) + record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.referral_invalid") + end end def validate_unitletas(record) diff --git a/app/views/form/page.html.erb b/app/views/form/page.html.erb index 3589a1c43..8961f2edc 100644 --- a/app/views/form/page.html.erb +++ b/app/views/form/page.html.erb @@ -30,6 +30,7 @@ <% end %> <%= form_with model: @case_log, url: form_case_log_path(@case_log), method: "post" do |f| %> + <% remove_other_page_errors(@case_log, @page) %> <%= f.govuk_error_summary %> <% @page.non_conditional_questions.map do |question| %>
<%= display_question_key_div(@page, question) %> > diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 54bfc0a50..b735e10e5 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -790,7 +790,7 @@ "hint_text": "", "type": "radio", "answer_options": { - "0": "Owner occupation (private) ", + "0": "Owner occupation (private)", "1": "Owner occupation (low cost home ownership)", "2": "Private sector tenancy", "3": "Tied housing or rented with job", @@ -3241,6 +3241,33 @@ } } } + }, + "referral": { + "header": "", + "description": "", + "questions": { + "referral": { + "check_answer_label": "Source of referral for letting", + "header": "What was the source of referral for this letting?", + "hint_text": "", + "type": "radio", + "answer_options": { + "0": "Internal transfer", + "1": "Tenant applied directly (no referral or nomination)", + "2": "Private registered provider (PRP) lettings only - nominated by a local housing authority", + "3": "Private registered provider (PRP) supported lettings only - referred by local authority housing department", + "4": "Re-located through official housing mobility scheme", + "5": "Other social landlord", + "6": "Community learning disability team", + "7": "Police, probation or prison", + "8": "Youth offending team", + "9": "Community mental health team", + "10": "Health service", + "11": "Voluntary agency", + "12": "Other" + } + } + } } } } diff --git a/config/locales/en.yml b/config/locales/en.yml index fd5690a4a..b8fe96c35 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -55,6 +55,8 @@ en: first_let_not_social: "Reason for vacancy cannot be first let if unit has been previously let as social housing" first_let_social: "Reason for vacancy must be first let if unit has been previously let as social housing" previous_let_social: "Property cannot have a previous let type if it is being let as social housing for the first time" + non_temp_accommodation: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as you already told us this accommodation is not temporary" + referral_invalid: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as you already told us a different source of referral for this letting" financial: tshortfall: @@ -100,6 +102,8 @@ en: one_bedroom_bedsit: "A bedsit can only have one bedroom" one_seven_bedroom_shared: "A shared house must have 1 to 7 bedrooms" one_three_bedroom_single_tenant_shared: "A shared house with less than two tenants must have 1 to 3 bedrooms" + prevten: + non_temp_accommodation: "Answer cannot be non-temporary accommodation as you already told us this is a re-let to tenant who occupied the same property as temporary accommodation" tenancy: length: @@ -107,6 +111,10 @@ en: shorthold: "Fixed term – Assured Shorthold Tenancy (AST) should be between 2 and 99 years" secure: "Secure (including flexible) should be between 2 and 99 years or not specified" + local_authority: + referral: + rsnvac_non_temp: "Answer cannot be this source of referral as you already told us this is a re-let to tenant who occupied the same property as temporary accommodation" + soft_validations: net_income: hint_text: "This is based on the tenant’s work situation: %{ecstat1}" diff --git a/db/migrate/20220124121642_add_referral_field.rb b/db/migrate/20220124121642_add_referral_field.rb new file mode 100644 index 000000000..c4fcec464 --- /dev/null +++ b/db/migrate/20220124121642_add_referral_field.rb @@ -0,0 +1,7 @@ +class AddReferralField < ActiveRecord::Migration[7.0] + def change + change_table :case_logs, bulk: true do |t| + t.column :referral, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 766b1cf55..52952738e 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.define(version: 2022_01_14_105351) do +ActiveRecord::Schema.define(version: 2022_01_24_121642) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -84,15 +84,9 @@ ActiveRecord::Schema.define(version: 2022_01_14_105351) do t.integer "beds" t.integer "offered" t.integer "wchair" - t.integer "earnings" t.integer "incfreq" t.integer "benefits" t.integer "period" - t.integer "brent" - t.integer "scharge" - t.integer "pscharge" - t.integer "supcharg" - t.integer "tcharge" t.integer "layear" t.integer "lawaitlist" t.string "property_postcode" @@ -143,7 +137,6 @@ ActiveRecord::Schema.define(version: 2022_01_14_105351) do t.string "prevloc" t.integer "hb" t.integer "hbrentshortfall" - t.integer "tshortfall" t.string "postcode" t.string "postcod2" t.string "ppostc1" @@ -181,9 +174,17 @@ ActiveRecord::Schema.define(version: 2022_01_14_105351) do t.string "has_benefits" t.integer "nocharge" t.integer "is_carehome" - t.decimal "chcharge" t.integer "letting_in_sheltered_accomodation" t.integer "household_charge" + t.integer "earnings" + t.integer "brent" + t.integer "scharge" + t.integer "pscharge" + t.integer "supcharg" + t.integer "tcharge" + t.integer "tshortfall" + t.integer "chcharge" + t.integer "referral" t.index ["discarded_at"], name: "index_case_logs_on_discarded_at" t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id" diff --git a/spec/helpers/form_page_error_helper.spec.rb b/spec/helpers/form_page_error_helper.spec.rb new file mode 100644 index 000000000..dc78bf2f8 --- /dev/null +++ b/spec/helpers/form_page_error_helper.spec.rb @@ -0,0 +1,24 @@ +require "rails_helper" + +RSpec.describe FormPageErrorHelper do + describe "#remove_other_page_errors" do + context "removes non base other questions" do + let!(:case_log) { FactoryBot.create(:case_log, :in_progress) } + let!(:form) { case_log.form } + + before do + case_log.errors.add :layear, "error" + case_log.errors.add :period, "error_one" + case_log.errors.add :base, "error_too" + end + + it "returns details and user tabs" do + page = form.get_page("rent") + remove_other_page_errors(case_log, page) + expect(case_log.errors.count).to eq(2) + expect(case_log.errors.map(&:attribute)).to include(:period) + expect(case_log.errors.map(&:attribute)).to include(:base) + end + end + end +end diff --git a/spec/models/case_log_spec.rb b/spec/models/case_log_spec.rb index 376641f78..2a0b5e43a 100644 --- a/spec/models/case_log_spec.rb +++ b/spec/models/case_log_spec.rb @@ -907,6 +907,43 @@ RSpec.describe Form, type: :model do }.to raise_error(ActiveRecord::RecordInvalid) end end + + context "Validate reason for vacancy" do + def check_rsnvac_validation(prevten) + expect { + CaseLog.create!(rsnvac: "Relet to tenant who occupied same property as temporary accommodation", + prevten: prevten, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) + }.to raise_error(ActiveRecord::RecordInvalid) + end + + def check_rsnvac_referral_validation(referral) + expect { + CaseLog.create!(rsnvac: "Relet to tenant who occupied same property as temporary accommodation", + referral: referral, + owning_organisation: owning_organisation, + managing_organisation: managing_organisation) + }.to raise_error(ActiveRecord::RecordInvalid) + end + + it "cannot be temp accomodation if previous tenancy was non temp" do + check_rsnvac_validation("Tied housing or rented with job") + check_rsnvac_validation("Supported housing") + check_rsnvac_validation("Sheltered accomodation") + check_rsnvac_validation("Home Office Asylum Support") + check_rsnvac_validation("Other") + end + + it "cannot be temp accomodation if source of letting referral " do + check_rsnvac_referral_validation("Re-located through official housing mobility scheme") + check_rsnvac_referral_validation("Other social landlord") + check_rsnvac_referral_validation("Police, probation or prison") + check_rsnvac_referral_validation("Youth offending team") + check_rsnvac_referral_validation("Community mental health team") + check_rsnvac_referral_validation("Health service") + end + end end describe "status" do