diff --git a/app/models/case_log.rb b/app/models/case_log.rb index 94b80f2c3..b8d860b6f 100644 --- a/app/models/case_log.rb +++ b/app/models/case_log.rb @@ -9,6 +9,7 @@ class CaseLogValidator < ActiveModel::Validator include Validations::DateValidations include Validations::LocalAuthorityValidations include Validations::SubmissionValidations + include DerivedVariables::CaseLogVariables def validate(record) validation_methods = public_methods.select { |method| method.starts_with?("validate_") } @@ -210,7 +211,7 @@ class CaseLog < ApplicationRecord end def is_fixed_term_tenancy? - [4, 6].include?(tenancy) + [4, 6, 7].include?(tenancy) end def is_secure_tenancy? @@ -262,10 +263,12 @@ class CaseLog < ApplicationRecord def previous_tenancy_was_temporary? # 4: Tied housing or renting with job # 6: Supported housing - # 8: Sheltered accomodation + # 8: Sheltered accomodation (<= 21/22) # 24: Housed by National Asylum Support Service (prev Home Office) # 25: Other - ![4, 6, 8, 24, 25].include?(prevten) + # 34: Specialist retirement housing + # 35: Extra care housing + ![4, 6, 8, 24, 25, 34, 35].include?(prevten) end def armed_forces_regular? @@ -298,11 +301,6 @@ class CaseLog < ApplicationRecord homeless == 11 end - def is_other_homeless? - # 7: Other homeless – not found statutorily homeless but considered homeless by landlord - homeless == 7 - end - def is_not_homeless? # 1: No homeless == 1 @@ -334,6 +332,7 @@ class CaseLog < ApplicationRecord hb == 1 end + # Option 8 has been removed starting from 22/23 def receives_housing_benefit_and_universal_credit? # 8: Housing benefit and Universal Credit (without housing element) hb == 8 @@ -359,8 +358,12 @@ class CaseLog < ApplicationRecord end def receives_housing_related_benefits? - receives_housing_benefit_only? || receives_uc_with_housing_element_excl_housing_benefit? || - receives_housing_benefit_and_universal_credit? + if collection_start_year <= 2021 + receives_housing_benefit_only? || receives_uc_with_housing_element_excl_housing_benefit? || + receives_housing_benefit_and_universal_credit? + else + receives_housing_benefit_only? || receives_uc_with_housing_element_excl_housing_benefit? + end end def benefits_unknown? @@ -518,64 +521,6 @@ private collection_start_year >= 2022 && !is_fixed_term_tenancy? end - def set_derived_fields! - # TODO: Remove once we support supported housing logs - self.needstype = 1 unless needstype - if rsnvac.present? - self.newprop = has_first_let_vacancy_reason? ? 1 : 2 - end - self.incref = 1 if net_income_refused? - self.renttype = RENT_TYPE_MAPPING[rent_type] - self.lettype = get_lettype - self.totchild = get_totchild - self.totelder = get_totelder - self.totadult = get_totadult - self.refused = get_refused - self.ethnic = 17 if ethnic_refused? - if %i[brent scharge pscharge supcharg].any? { |f| public_send(f).present? } - self.brent ||= 0 - self.scharge ||= 0 - self.pscharge ||= 0 - self.supcharg ||= 0 - self.tcharge = brent.to_f + scharge.to_f + pscharge.to_f + supcharg.to_f - end - if period.present? - self.wrent = weekly_value(brent) if brent.present? - self.wscharge = weekly_value(scharge) if scharge.present? - self.wpschrge = weekly_value(pscharge) if pscharge.present? - self.wsupchrg = weekly_value(supcharg) if supcharg.present? - self.wtcharge = weekly_value(tcharge) if tcharge.present? - if is_supported_housing? && chcharge.present? - self.wchchrg = weekly_value(chcharge) - end - end - self.has_benefits = get_has_benefits - self.tshortfall_known = 0 if tshortfall - self.wtshortfall = if tshortfall && receives_housing_related_benefits? - weekly_value(tshortfall) - end - self.nocharge = household_charge&.zero? ? 1 : 0 - self.housingneeds = get_housingneeds - if is_renewal? - self.underoccupation_benefitcap = 2 if collection_start_year == 2021 - self.homeless = 2 - self.referral = 0 - self.waityear = 1 - if is_general_needs? - # fixed term - self.prevten = 32 if managing_organisation.provider_type == "PRP" - self.prevten = 30 if managing_organisation.provider_type == "LA" - end - end - (2..8).each do |idx| - if age_under_16?(idx) - self["ecstat#{idx}"] = 9 - elsif public_send("ecstat#{idx}") == 9 && age_known?(idx) - self["ecstat#{idx}"] = nil - end - end - end - def age_under_16?(person_num) public_send("age#{person_num}") && public_send("age#{person_num}") < 16 end @@ -615,31 +560,6 @@ private self[postcode_key] = nil end - def get_totelder - ages = [age1, age2, age3, age4, age5, age6, age7, age8] - ages.count { |x| !x.nil? && x >= 60 } - end - - def get_totchild - relationships = [relat2, relat3, relat4, relat5, relat6, relat7, relat8] - relationships.count("C") - end - - def get_totadult - total = !age1.nil? && age1 >= 16 && age1 < 60 ? 1 : 0 - total + (2..8).count do |i| - age = public_send("age#{i}") - relat = public_send("relat#{i}") - !age.nil? && ((age >= 16 && age < 18 && %w[P X].include?(relat)) || age >= 18 && age < 60) - end - end - - def get_refused - return 1 if age_refused? || sex_refused? || relat_refused? || ecstat_refused? - - 0 - end - def get_inferred_la(postcode) # Avoid network calls when postcode is invalid return unless postcode.match(Validations::PropertyValidations::POSTCODE_REGEXP) diff --git a/app/models/derived_varables/case_log_variables.rb b/app/models/derived_varables/case_log_variables.rb new file mode 100644 index 000000000..eddff5620 --- /dev/null +++ b/app/models/derived_varables/case_log_variables.rb @@ -0,0 +1,166 @@ +module DerivedVariables::CaseLogVariables + def set_derived_fields! + # TODO: Remove once we support supported housing logs + self.needstype = 1 unless needstype + if rsnvac.present? + self.newprop = has_first_let_vacancy_reason? ? 1 : 2 + end + self.incref = 1 if net_income_refused? + self.renttype = RENT_TYPE_MAPPING[rent_type] + self.lettype = get_lettype + self.totchild = get_totchild + self.totelder = get_totelder + self.totadult = get_totadult + self.refused = get_refused + self.ethnic = 17 if ethnic_refused? + if %i[brent scharge pscharge supcharg].any? { |f| public_send(f).present? } + self.brent ||= 0 + self.scharge ||= 0 + self.pscharge ||= 0 + self.supcharg ||= 0 + self.tcharge = brent.to_f + scharge.to_f + pscharge.to_f + supcharg.to_f + end + if period.present? + self.wrent = weekly_value(brent) if brent.present? + self.wscharge = weekly_value(scharge) if scharge.present? + self.wpschrge = weekly_value(pscharge) if pscharge.present? + self.wsupchrg = weekly_value(supcharg) if supcharg.present? + self.wtcharge = weekly_value(tcharge) if tcharge.present? + if is_supported_housing? && chcharge.present? + self.wchchrg = weekly_value(chcharge) + end + end + self.has_benefits = get_has_benefits + self.tshortfall_known = 0 if tshortfall + self.wtshortfall = if tshortfall && receives_housing_related_benefits? + weekly_value(tshortfall) + end + self.nocharge = household_charge&.zero? ? 1 : 0 + self.housingneeds = get_housingneeds + if is_renewal? + self.underoccupation_benefitcap = 2 if collection_start_year == 2021 + self.homeless = 1 + self.referral = 0 + self.waityear = 2 + if is_general_needs? + # fixed term + self.prevten = 32 if managing_organisation.provider_type == "PRP" + self.prevten = 30 if managing_organisation.provider_type == "LA" + end + end + + child_under_16_constraints! + + self.hhtype = household_type + self.new_old = new_or_existing_tenant + self.vacdays = property_vacant_days + end + +private + + def get_totelder + ages = [age1, age2, age3, age4, age5, age6, age7, age8] + ages.count { |x| !x.nil? && x >= 60 } + end + + def get_totchild + relationships = [relat2, relat3, relat4, relat5, relat6, relat7, relat8] + relationships.count("C") + end + + def get_totadult + total = !age1.nil? && age1 >= 16 && age1 < 60 ? 1 : 0 + total + (2..8).count do |i| + age = public_send("age#{i}") + relat = public_send("relat#{i}") + !age.nil? && ((age >= 16 && age < 18 && %w[P X].include?(relat)) || age >= 18 && age < 60) + end + end + + def get_refused + return 1 if age_refused? || sex_refused? || relat_refused? || ecstat_refused? + + 0 + end + + def child_under_16_constraints! + (2..8).each do |idx| + if age_under_16?(idx) + self["ecstat#{idx}"] = 9 + elsif public_send("ecstat#{idx}") == 9 && age_known?(idx) + self["ecstat#{idx}"] = nil + end + end + end + + def household_type + return unless totelder && totadult && totchild + + if only_one_elder? + 1 + elsif two_adults_including_elders? + 2 + elsif only_one_adult? + 3 + elsif only_two_adults? + 4 + elsif one_adult_with_at_least_one_child? + 5 + elsif two_adults_with_at_least_one_child? + 6 + else + 9 + end + end + + def two_adults_with_at_least_one_child? + totelder.zero? && totadult >= 2 && totchild >= 1 + end + + def one_adult_with_at_least_one_child? + totelder.zero? && totadult == 1 && totchild >= 1 + end + + def only_two_adults? + totelder.zero? && totadult == 2 && totchild.zero? + end + + def only_one_adult? + totelder.zero? && totadult == 1 && totchild.zero? + end + + def two_adults_including_elders? + (totelder + totadult) == 2 && totelder >= 1 + end + + def only_one_elder? + totelder == 1 && totadult.zero? && totchild.zero? + end + + def new_or_existing_tenant + return unless startdate + + referral_within_sector = [1, 10] + if collection_start_year <= 2021 + previous_social_tenancies = [6, 8, 30, 31, 32, 33] + else + previous_social_tenancies = [6, 30, 31, 32, 33, 34, 35] + end + + if previous_social_tenancies.include?(prevten) || referral_within_sector.include?(referral) + 2 # Tenant existing in social housing sector + else + 1 # Tenant new to social housing sector + end + end + + def property_vacant_days + return unless startdate + + if mrcdate.present? + (startdate - mrcdate).to_i / 1.day + elsif voiddate.present? + (startdate - voiddate).to_i / 1.day + end + end +end diff --git a/app/services/exports/case_log_export_service.rb b/app/services/exports/case_log_export_service.rb index a73f7fde8..3de65608c 100644 --- a/app/services/exports/case_log_export_service.rb +++ b/app/services/exports/case_log_export_service.rb @@ -179,84 +179,15 @@ module Exports # Mapping which would require a change in our data model attribute_hash["createddate"] = attribute_hash["created_at"] attribute_hash["uploaddate"] = attribute_hash["updated_at"] - attribute_hash["tenancycode"] = attribute_hash["tenant_code"] - attribute_hash["ppcodenk"] = attribute_hash["previous_postcode_known"] - attribute_hash["sheltered"] = attribute_hash["shelteredaccom"] # Age refused (1..8).each do |index| attribute_hash["age#{index}"] = -9 if attribute_hash["age#{index}_known"] == 1 end - attribute_hash["hhtype"] = get_hhtype(case_log) - attribute_hash["new_old"] = get_new_old(case_log) - attribute_hash["vacdays"] = get_vacdays(case_log) - attribute_hash end - def get_vacdays(case_log) - return if case_log.startdate.nil? - - if case_log.mrcdate.present? - (case_log.startdate - case_log.mrcdate).to_i / 1.day - elsif case_log.voiddate.present? - (case_log.startdate - case_log.voiddate).to_i / 1.day - end - end - - def get_new_old(case_log) - if [6, 8, 30, 31, 32, 33].include?(case_log.prevten) || [1, 10].include?(case_log.referral) - 2 # Tenant existing in social housing sector - else - 1 # Tenant new to social housing sector - end - end - - def get_hhtype(case_log) - return if case_log.totelder.nil? || case_log.totadult.nil? || case_log.totchild.nil? - - if only_one_elder?(case_log) - 1 - elsif two_adults_including_elders?(case_log) - 2 - elsif only_one_adult?(case_log) - 3 - elsif only_two_adults?(case_log) - 4 - elsif one_adult_with_at_least_one_child?(case_log) - 5 - elsif two_adults_with_at_least_one_child?(case_log) - 6 - else - 9 - end - end - - def two_adults_with_at_least_one_child?(case_log) - case_log.totelder.zero? && case_log.totadult >= 2 && case_log.totchild >= 1 - end - - def one_adult_with_at_least_one_child?(case_log) - case_log.totelder.zero? && case_log.totadult == 1 && case_log.totchild >= 1 - end - - def only_two_adults?(case_log) - case_log.totelder.zero? && case_log.totadult == 2 && case_log.totchild.zero? - end - - def only_one_adult?(case_log) - case_log.totelder.zero? && case_log.totadult == 1 && case_log.totchild.zero? - end - - def two_adults_including_elders?(case_log) - (case_log.totelder + case_log.totadult) == 2 && case_log.totelder >= 1 - end - - def only_one_elder?(case_log) - case_log.totelder == 1 && case_log.totadult.zero? && case_log.totchild.zero? - end - def filter_keys!(attributes) attributes.reject! { |attribute| is_omitted_field?(attribute) } end diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index ce32663f0..dd30896e9 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -5328,6 +5328,9 @@ }, "3": { "value": "Person prefers not to say" + }, + "6": { + "value": "Don’t know" } } } @@ -5689,9 +5692,6 @@ "hint_text": "", "type": "radio", "answer_options": { - "1": { - "value": "Just moved to local authority area" - }, "2": { "value": "Less than 1 year" }, diff --git a/db/migrate/20220613123730_add_export_fields.rb b/db/migrate/20220613123730_add_export_fields.rb new file mode 100644 index 000000000..01176abd3 --- /dev/null +++ b/db/migrate/20220613123730_add_export_fields.rb @@ -0,0 +1,12 @@ +class AddExportFields < ActiveRecord::Migration[7.0] + def change + change_table :case_logs, bulk: true do |t| + t.column :hhtype, :integer + t.column :new_old, :integer + t.column :vacdays, :integer + t.rename :tenant_code, :tenancycode + t.rename :previous_postcode_known, :ppcodenk + t.rename :shelteredaccom, :sheltered + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4cca6211e..a9db14eab 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.0].define(version: 2022_06_06_082639) do +ActiveRecord::Schema[7.0].define(version: 2022_06_13_123730) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -18,7 +18,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_06_082639) do t.integer "status", default: 0 t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "tenant_code" + t.string "tenancycode" t.integer "age1" t.string "sex1" t.integer "ethnic" @@ -143,7 +143,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_06_082639) do t.decimal "tshortfall", precision: 10, scale: 2 t.decimal "chcharge", precision: 10, scale: 2 t.integer "declaration" - t.integer "previous_postcode_known" + t.integer "ppcodenk" t.integer "previous_la_known" t.boolean "is_previous_la_inferred" t.integer "age1_known" @@ -193,9 +193,12 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_06_082639) do t.bigint "created_by_id" t.integer "illness_type_0" t.integer "tshortfall_known" - t.integer "shelteredaccom" + t.integer "sheltered" t.integer "retirement_value_check" t.integer "pregnancy_value_check" + t.integer "hhtype" + t.integer "new_old" + t.integer "vacdays" t.index ["created_by_id"], name: "index_case_logs_on_created_by_id" t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" t.index ["old_id"], name: "index_case_logs_on_old_id", unique: true