From 7a9ad40a43c6d49e12cc4ac5870511902fe70dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Meny?= Date: Thu, 13 Jan 2022 14:30:55 +0000 Subject: [PATCH] CLDC-913: Export validation messages into i18n language file (#218) --- app/models/validations/date_validations.rb | 14 ++-- .../validations/financial_validations.rb | 14 ++-- .../validations/household_validations.rb | 44 +++++----- .../local_authority_validations.rb | 2 +- .../validations/property_validations.rb | 12 +-- app/models/validations/soft_validations.rb | 8 +- app/models/validations/tenancy_validations.rb | 6 +- config/locales/en.yml | 84 +++++++++++++++++++ 8 files changed, 134 insertions(+), 50 deletions(-) diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb index f29fe6be6..cdc30488d 100644 --- a/app/models/validations/date_validations.rb +++ b/app/models/validations/date_validations.rb @@ -2,29 +2,29 @@ module Validations::DateValidations def validate_property_major_repairs(record) date_valid?("mrcdate", record) if record["startdate"].present? && record["mrcdate"].present? && record["startdate"] < record["mrcdate"] - record.errors.add :mrcdate, "Major repairs date must be before the tenancy start date" + record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.before_tenancy_start") end if is_rsnvac_first_let?(record) && record["mrcdate"].present? - record.errors.add :mrcdate, "Major repairs date must not be completed if the tenancy is first let" + record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.not_first_let") end if record["mrcdate"].present? && record["startdate"].present? && record["startdate"].to_date - record["mrcdate"].to_date > 730 - record.errors.add :mrcdate, "The major repairs completion date should be no more than 730 days before the tenancy start date" + record.errors.add :mrcdate, I18n.t("validations.property.mrcdate.730_days_before_tenancy_start") end end def validate_property_void_date(record) if record["property_void_date"].present? && record["startdate"].present? && record["startdate"].to_date - record["property_void_date"].to_date > 3650 - record.errors.add :property_void_date, "The void date must be no more than 10 years before the tenancy start date" + record.errors.add :property_void_date, I18n.t("validations.property.void_date.ten_years_before_tenancy_start") end if record["property_void_date"].present? && record["startdate"].present? && record["startdate"].to_date < record["property_void_date"].to_date - record.errors.add :property_void_date, "Void date must be before the tenancy start date" + record.errors.add :property_void_date, I18n.t("validations.property.void_date.before_tenancy_start") end if record["property_void_date"].present? && record["mrcdate"].present? && record["mrcdate"].to_date < record["property_void_date"].to_date - record.errors.add :property_void_date, "Void date must be after the major repair date if a major repair date has been provided" + record.errors.add :property_void_date, I18n.t("validations.property.void_date.after_mrcdate") end end @@ -40,7 +40,7 @@ private def date_valid?(question, record) if record[question].is_a?(ActiveSupport::TimeWithZone) && record[question].year.zero? - record.errors.add question, "Please enter a valid date" + record.errors.add question, I18n.t("validations.date") end end diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index e5681dda6..c9088d30c 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -3,10 +3,10 @@ module Validations::FinancialValidations # or 'validate_' to run on submit as well def validate_outstanding_rent_amount(record) if record.hbrentshortfall == "Yes" && record.tshortfall.blank? - record.errors.add :tshortfall, "You must answer the oustanding amout question if you have outstanding rent or charges." + record.errors.add :tshortfall, I18n.t("validations.financial.tshortfall.outstanding_amount_required") end if record.hbrentshortfall == "No" && record.tshortfall.present? - record.errors.add :tshortfall, "You must not answer the oustanding amout question if you don't have outstanding rent or charges." + record.errors.add :tshortfall, I18n.t("validations.financial.tshortfall.outstanding_amount_not_required") end end @@ -18,7 +18,7 @@ module Validations::FinancialValidations relationship = record["relat#{n}"] is_partner_or_main = relationship == "Partner" || (relationship.nil? && economic_status.present?) if is_employed && is_partner_or_main && record.benefits == "All" - record.errors.add :benefits, "income is from Universal Credit, state pensions or benefits cannot be All if the tenant or the partner works part or full time" + record.errors.add :benefits, I18n.t("validations.financial.benefits.part_or_full_time") end end end @@ -27,11 +27,11 @@ module Validations::FinancialValidations return unless record.ecstat1 && record.weekly_net_income if record.weekly_net_income > record.applicable_income_range.hard_max - record.errors.add :earnings, "Net income cannot be greater than #{record.applicable_income_range.hard_max} given the tenant's working situation" + record.errors.add :earnings, I18n.t("validations.financial.earnings.under_hard_max", hard_max: record.applicable_income_range.hard_max) end if record.weekly_net_income < record.applicable_income_range.hard_min - record.errors.add :earnings, "Net income cannot be less than #{record.applicable_income_range.hard_min} given the tenant's working situation" + record.errors.add :earnings, I18n.t("validations.financial.earnings.over_hard_min", hard_min: record.applicable_income_range.hard_min) end end @@ -46,8 +46,8 @@ module Validations::FinancialValidations hb_and_uc = record.hb == "Housing benefit and Universal Credit (without housing element)" conditions = [ - { condition: is_yes && (hb_donotknow || hb_none || hb_uc_no_hb), error: "Outstanding amount for basic rent and/or benefit eligible charges can not be 'Yes' if tenant is not in receipt of housing benefit or universal benefit or if benefit is unknown" }, - { condition: (hb_no_uc || hb_uc_no_he_hb || hb_and_uc) && !is_present, error: "Must be completed if Universal credit and/or Housing Benefit received" }, + { condition: is_yes && (hb_donotknow || hb_none || hb_uc_no_hb), error: I18n.t("validations.financial.hbrentshortfall.outstanding_no_benefits") }, + { condition: (hb_no_uc || hb_uc_no_he_hb || hb_and_uc) && !is_present, error: I18n.t("validations.financial.hbrentshortfall.amount_required") }, ] conditions.each { |condition| condition[:condition] ? (record.errors.add :hbrentshortfall, condition[:error]) : nil } diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb index 4ff7fff56..56982f65b 100644 --- a/app/models/validations/household_validations.rb +++ b/app/models/validations/household_validations.rb @@ -3,14 +3,14 @@ module Validations::HouseholdValidations # or 'validate_' to run on submit as well def validate_reasonable_preference(record) if record.homeless == "No" && record.reasonpref == "Yes" - record.errors.add :reasonpref, "Can not be Yes if Not Homeless immediately prior to this letting has been selected" + record.errors.add :reasonpref, I18n.t("validations.household.reasonpref.not_homeless") elsif record.reasonpref == "Yes" if [record.rp_homeless, record.rp_insan_unsat, record.rp_medwel, record.rp_hardship, record.rp_dontknow].none? { |a| a == "Yes" } - record.errors.add :reasonable_preference_reason, 'If reasonable preference is "Yes", a reason must be given' + record.errors.add :reasonable_preference_reason, I18n.t("validations.household.reasonable_preference_reason.reason_required") end elsif record.reasonpref == "No" if [record.rp_homeless, record.rp_insan_unsat, record.rp_medwel, record.rp_hardship, record.rp_dontknow].any? { |a| a == "Yes" } - record.errors.add :reasonable_preference_reason, 'If reasonable preference is "No", no reasons should be given' + record.errors.add :reasonable_preference_reason, I18n.t("validations.household.reasonable_preference_reason.reason_not_required") end end end @@ -21,33 +21,33 @@ module Validations::HouseholdValidations def validate_reason_for_leaving_last_settled_home(record) if record.reason == "Don’t know" && record.underoccupation_benefitcap != "Don’t know" - record.errors.add :underoccupation_benefitcap, "must be don’t know if tenant’s main reason for leaving is don’t know" + record.errors.add :underoccupation_benefitcap, I18n.t("validations.household.underoccupation_benefitcap.dont_know_required") end end def validate_armed_forces_injured(record) if (record.armedforces == "A current or former regular in the UK Armed Forces (excluding National Service)" || record.armedforces == "A current or former reserve in the UK Armed Forces (excluding National Service)") && record.reservist.blank? - record.errors.add :reservist, "You must answer the armed forces injury question if the tenant has served in the armed forces" + record.errors.add :reservist, I18n.t("validations.household.reservist.injury_required") end if (record.armedforces == "No" || record.armedforces == "Prefer not to say") && record.reservist.present? - record.errors.add :reservist, "You must not answer the armed forces injury question if the tenant has not served in the armed forces or prefer not to say was chosen" + record.errors.add :reservist, I18n.t("validations.household.reservist.injury_not_required") end end def validate_armed_forces_active_response(record) if record.armedforces == "A current or former regular in the UK Armed Forces (excluding National Service)" && record.leftreg.blank? - record.errors.add :leftreg, "You must answer the armed forces active question if the tenant has served as a regular in the armed forces" + record.errors.add :leftreg, I18n.t("validations.household.leftreg.question_required") end if record.armedforces != "A current or former regular in the UK Armed Forces (excluding National Service)" && record.leftreg.present? - record.errors.add :leftreg, "You must not answer the armed forces active question if the tenant has not served as a regular in the armed forces" + record.errors.add :leftreg, I18n.t("validations.household.leftreg.question_not_required") end end def validate_pregnancy(record) if (record.preg_occ == "Yes" || record.preg_occ == "Prefer not to say") && !women_of_child_bearing_age_in_household(record) - record.errors.add :preg_occ, "You must answer no as there are no female tenants aged 16-50 in the property" + record.errors.add :preg_occ, I18n.t("validations.household.preg_occ.no_female") end end @@ -66,7 +66,7 @@ module Validations::HouseholdValidations return unless record.age1 if !record.age1.is_a?(Integer) || record.age1 < 16 || record.age1 > 120 - record.errors.add :age1, "Tenant age must be an integer between 16 and 120" + record.errors.add :age1, I18n.t("validations.household.age.over_16") end end @@ -79,7 +79,7 @@ module Validations::HouseholdValidations if all_options.count("Yes") > 1 mobility_accessibility_options = [record.housingneeds_a, record.housingneeds_b, record.housingneeds_c] unless all_options.count("Yes") == 2 && record.housingneeds_f == "Yes" && mobility_accessibility_options.any? { |x| x == "Yes" } - record.errors.add :housingneeds_a, "Only one box must be ticked or 'other disabilities' plus one of mobility disabilities" + record.errors.add :housingneeds_a, I18n.t("validations.household.housingneeds_a.one_or_two_choices") end end end @@ -87,15 +87,15 @@ module Validations::HouseholdValidations def validate_shared_housing_rooms(record) unless record.unittype_gn.nil? if record.unittype_gn == "Bedsit" && record.beds != 1 && record.beds.present? - record.errors.add :unittype_gn, "A bedsit can only have one bedroom" + record.errors.add :unittype_gn, I18n.t("validations.household.unittype_gn.one_bedroom_bedsit") end if !record.other_hhmemb.nil? && record.other_hhmemb.positive? && (record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 7)) - record.errors.add :unittype_gn, "A shared house must have 1 to 7 bedrooms" + record.errors.add :unittype_gn, I18n.t("validations.household.unittype_gn.one_seven_bedroom_shared") end if record.unittype_gn.include?("Shared") && !record.beds.to_i.between?(1, 3) && record.beds.present? - record.errors.add :unittype_gn, "A shared house with less than two tenants must have 1 to 3 bedrooms" + record.errors.add :unittype_gn, I18n.t("validations.household.unittype_gn.one_three_bedroom_single_tenant_shared") end end end @@ -115,7 +115,7 @@ private return unless age if !age.is_a?(Integer) || age < 1 || age > 120 - record.errors.add "age#{person_num}".to_sym, "Tenant age must be an integer between 0 and 120" + record.errors.add "age#{person_num}".to_sym, I18n.t("validations.household.age.must_be_valid") end end @@ -125,10 +125,10 @@ private return unless age && economic_status if age > 70 && economic_status != "Retired" - record.errors.add "ecstat#{person_num}", "Tenant #{person_num} must be retired if over 70" + record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.retired_over_70", person_num: person_num) end if age < 16 && economic_status != "Child under 16" - record.errors.add "ecstat#{person_num}", "Tenant #{person_num} economic status must be Child under 16 if their age is under 16" + record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.child_under_16", person_num: person_num) end end @@ -138,7 +138,7 @@ private return unless age && relationship if age < 16 && relationship != "Child - includes young adult and grown-up" - record.errors.add "relat#{person_num}", "Tenant #{person_num}'s relationship to tenant 1 must be Child if their age is under 16" + record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_under_16", person_num: person_num) end end @@ -149,7 +149,7 @@ private return unless age && economic_status && relationship if age >= 16 && age <= 19 && relationship == "Child - includes young adult and grown-up" && (economic_status != "Full-time student" || economic_status != "Prefer not to say") - record.errors.add "ecstat#{person_num}", "If age is between 16 and 19 - tenant #{person_num} must be a full time student or prefer not to say." + record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19", person_num: person_num) end end @@ -160,10 +160,10 @@ private return unless age && economic_status && gender if gender == "Male" && economic_status == "Retired" && age < 65 - record.errors.add "age#{person_num}", "Male tenant who is retired must be 65 or over" + record.errors.add "age#{person_num}", I18n.t("validations.household.age.retired_male") end if gender == "Female" && economic_status == "Retired" && age < 60 - record.errors.add "age#{person_num}", "Female tenant who is retired must be 60 or over" + record.errors.add "age#{person_num}", I18n.t("validations.household.age.retired_female") end end @@ -171,7 +171,7 @@ private # TODO: probably need to keep track of which specific field is wrong so we can highlight it in the UI partner_count = (2..8).count { |n| record.public_send("relat#{n}") == "Partner" } if partner_count > 1 - record.errors.add :base, "Number of partners cannot be greater than 1" + record.errors.add :base, I18n.t("validations.household.relat.one_partner") end end end diff --git a/app/models/validations/local_authority_validations.rb b/app/models/validations/local_authority_validations.rb index cae230900..b4b6d8f1c 100644 --- a/app/models/validations/local_authority_validations.rb +++ b/app/models/validations/local_authority_validations.rb @@ -4,7 +4,7 @@ module Validations::LocalAuthorityValidations def validate_previous_accommodation_postcode(record) postcode = record.previous_postcode if postcode.present? && !postcode.match(POSTCODE_REGEXP) - error_message = "Enter a postcode in the correct format, for example AA1 1AA" + error_message = I18n.t("validations.postcode") record.errors.add :previous_postcode, error_message end end diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index 4d6792cd5..0668c066c 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -7,13 +7,13 @@ module Validations::PropertyValidations def validate_property_number_of_times_relet(record) if record.offered && !/^[1-9]$|^0[1-9]$|^1[0-9]$|^20$/.match?(record.offered.to_s) - record.errors.add :offered, "Property number of times relet must be between 0 and 20" + record.errors.add :offered, I18n.t("validations.property.offered.relet_number") end end def validate_la(record) if record.la.present? && !LONDON_BOROUGHS.include?(record.la) && (record.rent_type == "London Affordable rent" || record.rent_type == "London living rent") - record.errors.add :la, "Local authority has to be in London" + record.errors.add :la, I18n.t("validations.property.la.london_rent") end end @@ -22,24 +22,24 @@ module Validations::PropertyValidations "First let of leased property"].freeze def validate_rsnvac(record) if !record.first_time_property_let_as_social_housing? && FIRST_LET_VACANCY_REASONS.include?(record.rsnvac) - record.errors.add :rsnvac, "Reason for vacancy cannot be first let if unit has been previously let as social housing" + record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.first_let_not_social") end if record.first_time_property_let_as_social_housing? && record.rsnvac.present? && !FIRST_LET_VACANCY_REASONS.include?(record.rsnvac) - record.errors.add :rsnvac, "Reason for vacancy must be first let if unit has been previously let as social housing" + record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.first_let_social") end end def validate_unitletas(record) if record.first_time_property_let_as_social_housing? && record.unitletas.present? - record.errors.add :unitletas, "Property cannot have a previous let type if it is being let as social housing for the first time" + record.errors.add :unitletas, I18n.t("validations.property.rsnvac.previous_let_social") end end def validate_property_postcode(record) postcode = record.property_postcode if record.postcode_known == "Yes" && (postcode.blank? || !postcode.match(POSTCODE_REGEXP)) - error_message = "Enter a postcode in the correct format, for example AA1 1AA" + error_message = I18n.t("validations.postcode") record.errors.add :property_postcode, error_message end end diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index 176a6cde5..087874a8d 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -17,13 +17,13 @@ private net_income_errors = {} if net_income_in_soft_min_range? net_income_errors["override_net_income_validation"] = OpenStruct.new( - message: "Net income is lower than expected based on the main tenant's working situation. Are you sure this is correct?", - hint_text: "This is based on the tenant's work situation: #{ecstat1}", + message: I18n.t("soft_validations.net_income.in_soft_min_range.message"), + hint_text: I18n.t("soft_validations.net_income.hint_text", ecstat1: ecstat1), ) elsif net_income_in_soft_max_range? net_income_errors["override_net_income_validation"] = OpenStruct.new( - message: "Net income is higher than expected based on the main tenant's working situation. Are you sure this is correct?", - hint_text: "This is based on the tenant's work situation: #{ecstat1}", + message: I18n.t("soft_validations.net_income.in_soft_max_range.message"), + hint_text: I18n.t("soft_validations.net_income.hint_text", ecstat1: ecstat1), ) else update_column(:override_net_income_validation, nil) diff --git a/app/models/validations/tenancy_validations.rb b/app/models/validations/tenancy_validations.rb index ee74e74f5..a6c9df483 100644 --- a/app/models/validations/tenancy_validations.rb +++ b/app/models/validations/tenancy_validations.rb @@ -7,9 +7,9 @@ module Validations::TenancyValidations is_secure = record.tenancy == "Secure (including flexible)" is_ast = record.tenancy == "Assured Shorthold" conditions = [ - { condition: !(is_secure || is_ast) && is_present, error: "You must only answer the fixed term tenancy length question if the tenancy type is fixed term" }, - { condition: is_ast && !is_in_range, error: "Fixed term – Assured Shorthold Tenancy (AST) should be between 2 and 99 years" }, - { condition: is_secure && (!is_in_range && is_present), error: "Secure (including flexible) should be between 2 and 99 years or not specified" }, + { condition: !(is_secure || is_ast) && is_present, error: I18n.t("validations.tenancy.length.fixed_term_not_required") }, + { condition: is_ast && !is_in_range, error: I18n.t("validations.tenancy.length.shorthold") }, + { condition: is_secure && (!is_in_range && is_present), error: I18n.t("validations.tenancy.length.secure") }, ] conditions.each { |condition| condition[:condition] ? (record.errors.add :tenancylength, condition[:error]) : nil } diff --git a/config/locales/en.yml b/config/locales/en.yml index 3de49c379..9163aaefd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -33,3 +33,87 @@ en: service_name: "Submit social housing lettings and sales data (CORE)" organisation: updated: "Organisation details updated" + + validations: + date: "Please enter a valid date" + postcode: "Enter a postcode in the correct format, for example AA1 1AA" + + property: + mrcdate: + before_tenancy_start: "Major repairs date must be before the tenancy start date" + not_first_let: "Major repairs date must not be completed if the tenancy is first let" + 730_days_before_tenancy_start: "The major repairs completion date should be no more than 730 days before the tenancy start date" + void_date: + ten_years_before_tenancy_start: "The void date must be no more than 10 years before the tenancy start date" + before_tenancy_start: "Void date must be before the tenancy start date" + after_mrcdate: "Void date must be after the major repair date if a major repair date has been provided" + offered: + relet_number: "Property number of times relet must be between 0 and 20" + la: + london_rent: "Local authority has to be in London" + rsnvac: + 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" + + financial: + tshortfall: + outstanding_amount_required: "You must answer the outstanding amount question if you have outstanding rent or charges." + outstanding_amount_not_required: "You must not answer the outstanding amount question if you don't have outstanding rent or charges." + hbrentshortfall: + outstanding_no_benefits: "Outstanding amount for basic rent and/or benefit eligible charges can not be 'Yes' if tenant is not in receipt of housing benefit or universal benefit or if benefit is unknown" + amount_required: "Must be completed if Universal credit and/or Housing Benefit received" + benefits: + part_or_full_time: "income is from Universal Credit, state pensions or benefits cannot be All if the tenant or the partner works part or full time" + earnings: + under_hard_max: "Net income cannot be greater than %{hard_max} given the tenant's working situation" + over_hard_min: "Net income cannot be less than %{hard_min} given the tenant's working situation" + + household: + reasonpref: + not_homeless: "Can not be Yes if Not Homeless immediately prior to this letting has been selected" + reasonable_preference_reason: + reason_required: "If reasonable preference is \"Yes\", a reason must be given" + reason_not_required: "If reasonable preference is \"No\", no reasons should be given" + underoccupation_benefitcap: + dont_know_required: "must be don’t know if tenant’s main reason for leaving is don’t know" + reservist: + injury_required: "You must answer the armed forces injury question if the tenant has served in the armed forces" + injury_not_required: "You must not answer the armed forces injury question if the tenant has not served in the armed forces or prefer not to say was chosen" + leftreg: + question_required: "You must answer the armed forces active question if the tenant has served as a regular in the armed forces" + question_not_required: "You must not answer the armed forces active question if the tenant has not served as a regular in the armed forces" + preg_occ: + no_female: "You must answer no as there are no female tenants aged 16-50 in the property" + age: + over_16: "Tenant age must be an integer between 16 and 120" + must_be_valid: "Tenant age must be an integer between 0 and 120" + retired_male: "Male tenant who is retired must be 65 or over" + retired_female: "Female tenant who is retired must be 60 or over" + ecstat: + retired_over_70: "Tenant %{person_num} must be retired if over 70" + child_under_16: "Tenant %{person_num} economic status must be Child under 16 if their age is under 16" + student_16_19: "If age is between 16 and 19 - tenant %{person_num} must be a full time student or prefer not to say." + relat: + child_under_16: "Tenant %{person_num}'s relationship to tenant 1 must be Child if their age is under 16" + one_partner: "Number of partners cannot be greater than 1" + housingneeds_a: + one_or_two_choices: "Only one box must be ticked or 'other disabilities' plus one of mobility disabilities" + unittype_gn: + 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" + + tenancy: + length: + fixed_term_not_required: "You must only answer the fixed term tenancy length question if the tenancy type is fixed term" + 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" + + soft_validations: + net_income: + hint_text: "This is based on the tenant's work situation: %{ecstat1}" + in_soft_min_range: + message: "Net income is lower than expected based on the main tenant's working situation. Are you sure this is correct?" + in_soft_max_range: + message: "Net income is higher than expected based on the main tenant's working situation. Are you sure this is correct?"