From e5eae1c19b8fc5ec30a9954dbe61039fa8941214 Mon Sep 17 00:00:00 2001 From: Oscar Richardson <116292912+oscar-richardson-softwire@users.noreply.github.com> Date: Mon, 23 Feb 2026 17:49:51 +0000 Subject: [PATCH 1/2] CLDC-4139: Tenancy type other free text validation (#3174) * Add functionality * Fix/add tests * Update config/locales/forms/2026/lettings/soft_validations.en.yml Co-authored-by: Samuel Young * Update after PO feedback * Fix tests after rebase --------- Co-authored-by: Samuel Young --- .../pages/tenancyother_value_check.rb | 24 ++++++++++++ .../questions/tenancyother_value_check.rb | 13 +++++++ .../subsections/tenancy_information.rb | 1 + app/models/validations/soft_validations.rb | 10 +++++ .../2026/lettings/soft_validations.en.yml | 17 +++++++++ ...nancyother_value_check_to_lettings_logs.rb | 5 +++ db/schema.rb | 3 +- .../lettings_log_csv_export_codes_26.csv | 6 +-- .../lettings_log_csv_export_labels_26.csv | 6 +-- .../subsections/tenancy_information_spec.rb | 20 ++++++++++ .../validations/soft_validations_spec.rb | 38 +++++++++++++++++++ 11 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 app/models/form/lettings/pages/tenancyother_value_check.rb create mode 100644 app/models/form/lettings/questions/tenancyother_value_check.rb create mode 100644 db/migrate/20260212091506_add_tenancyother_value_check_to_lettings_logs.rb diff --git a/app/models/form/lettings/pages/tenancyother_value_check.rb b/app/models/form/lettings/pages/tenancyother_value_check.rb new file mode 100644 index 000000000..391b06eab --- /dev/null +++ b/app/models/form/lettings/pages/tenancyother_value_check.rb @@ -0,0 +1,24 @@ +class Form::Lettings::Pages::TenancyotherValueCheck < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "tenancyother_value_check" + @copy_key = "lettings.soft_validations.tenancyother_value_check" + @depends_on = [{ "tenancyother_might_be_introductory_or_starter_period?" => true }] + @title_text = { + "translation" => "forms.#{form.start_date.year}.#{@copy_key}.title_text", + "arguments" => [{ "key" => "tenancyother", "i18n_template" => "tenancyother" }], + } + @informative_text = { + "translation" => "forms.#{form.start_date.year}.#{@copy_key}.informative_text", + "arguments" => [], + } + end + + def questions + @questions ||= [Form::Lettings::Questions::TenancyotherValueCheck.new(nil, nil, self)] + end + + def interruption_screen_question_ids + %w[startertenancy tenancy tenancyother] + end +end diff --git a/app/models/form/lettings/questions/tenancyother_value_check.rb b/app/models/form/lettings/questions/tenancyother_value_check.rb new file mode 100644 index 000000000..309de7169 --- /dev/null +++ b/app/models/form/lettings/questions/tenancyother_value_check.rb @@ -0,0 +1,13 @@ +class Form::Lettings::Questions::TenancyotherValueCheck < ::Form::Question + def initialize(id, hsh, page) + super + @id = "tenancyother_value_check" + @copy_key = "lettings.soft_validations.tenancyother_value_check" + @type = "interruption_screen" + @check_answers_card_number = 0 + @answer_options = ANSWER_OPTIONS + @hidden_in_check_answers = { "depends_on" => [{ "tenancyother_value_check" => 0 }, { "tenancyother_value_check" => 1 }] } + end + + ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze +end diff --git a/app/models/form/lettings/subsections/tenancy_information.rb b/app/models/form/lettings/subsections/tenancy_information.rb index b65039b8d..e6ff48457 100644 --- a/app/models/form/lettings/subsections/tenancy_information.rb +++ b/app/models/form/lettings/subsections/tenancy_information.rb @@ -12,6 +12,7 @@ class Form::Lettings::Subsections::TenancyInformation < ::Form::Subsection Form::Lettings::Pages::StarterTenancy.new("starter_tenancy", nil, self), Form::Lettings::Pages::TenancyType.new(nil, nil, self), Form::Lettings::Pages::StarterTenancyType.new(nil, nil, self), + (Form::Lettings::Pages::TenancyotherValueCheck.new(nil, nil, self) if form.start_year_2026_or_later?), Form::Lettings::Pages::TenancyLength.new(nil, nil, self), Form::Lettings::Pages::TenancyLengthAffordableRent.new(nil, nil, self), Form::Lettings::Pages::TenancyLengthIntermediateRent.new(nil, nil, self), diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index 9b6816dd1..ea17d0601 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -194,6 +194,16 @@ module Validations::SoftValidations PHRASES_LIKELY_TO_INDICATE_EXISTING_REASON_CATEGORY_REGEX.match?(reasonother) end + PHRASES_LIKELY_TO_INDICATE_INTRODUCTORY_OR_STARTER_PERIOD = %w[introductory intro starter].freeze + + PHRASES_LIKELY_TO_INDICATE_INTRODUCTORY_OR_STARTER_PERIOD_REGEX = Regexp.union( + PHRASES_LIKELY_TO_INDICATE_INTRODUCTORY_OR_STARTER_PERIOD.map { |phrase| Regexp.new("\\b[^[:alpha]]*#{phrase}[^[:alpha:]]*\\b", Regexp::IGNORECASE) }, + ) + + def tenancyother_might_be_introductory_or_starter_period? + PHRASES_LIKELY_TO_INDICATE_INTRODUCTORY_OR_STARTER_PERIOD_REGEX.match?(tenancyother) + end + def multiple_partners? return unless hhmemb diff --git a/config/locales/forms/2026/lettings/soft_validations.en.yml b/config/locales/forms/2026/lettings/soft_validations.en.yml index 74e7af46f..88bcaf1ea 100644 --- a/config/locales/forms/2026/lettings/soft_validations.en.yml +++ b/config/locales/forms/2026/lettings/soft_validations.en.yml @@ -57,6 +57,23 @@ en: title_text: "You told us that the tenant’s main reason for leaving their last settled home was %{reasonother}." informative_text: "The reason you have entered looks very similar to one of the existing response categories. Please check the categories and select the appropriate one. If the existing categories are not suitable, please confirm here to move onto the next question." + tenancyother_value_check: + page_header: "" + check_answer_label: "Tenancy other confirmation" + check_answer_prompt: "Confirm tenancy type" + hint_text: "" + question_text: "" + title_text: "You told us that the type of tenancy was %{tenancyother}." + informative_text: "We already know whether the tenancy is introductory or has a starter period from your previous answer. Your answer to the type of main tenancy question should be the type of tenancy that the tenant will roll onto after any introductory or starter period. Choose from the categories or write a description if no category is suitable." + referral_value_check: + page_header: "" + check_answer_label: "Referral confirmation" + check_answer_prompt: "Confirm referral type" + hint_text: "" + question_text: "Are you sure?" + title_text: "Are you sure?" + informative_text: "This is a general needs log, and this referral type is for supported housing." + net_income_value_check: page_header: "" check_answer_label: "Net income confirmation" diff --git a/db/migrate/20260212091506_add_tenancyother_value_check_to_lettings_logs.rb b/db/migrate/20260212091506_add_tenancyother_value_check_to_lettings_logs.rb new file mode 100644 index 000000000..339dc7a07 --- /dev/null +++ b/db/migrate/20260212091506_add_tenancyother_value_check_to_lettings_logs.rb @@ -0,0 +1,5 @@ +class AddTenancyotherValueCheckToLettingsLogs < ActiveRecord::Migration[7.0] + def change + add_column :lettings_logs, :tenancyother_value_check, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 19faeed2a..62d32713f 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.2].define(version: 2026_02_04_100051) do +ActiveRecord::Schema[7.2].define(version: 2026_02_12_091506) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -403,6 +403,7 @@ ActiveRecord::Schema[7.2].define(version: 2026_02_04_100051) do t.integer "referral_register" t.integer "referral_noms" t.integer "referral_org" + t.integer "tenancyother_value_check" t.index ["assigned_to_id"], name: "index_lettings_logs_on_assigned_to_id" t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id" diff --git a/spec/fixtures/files/lettings_log_csv_export_codes_26.csv b/spec/fixtures/files/lettings_log_csv_export_codes_26.csv index aacc8581d..b99c44ce8 100644 --- a/spec/fixtures/files/lettings_log_csv_export_codes_26.csv +++ b/spec/fixtures/files/lettings_log_csv_export_codes_26.csv @@ -1,3 +1,3 @@ -Log ID,Status of log,ID of a set of duplicate logs,User the log is created by,User the log is assigned to,Is the user in the assigned_to column the data protection officer?,Time and date the log was created,User who last updated the log,Time and date the log was last updated,Was the log submitted in-service or via bulk upload?,Year collection period opened,ID of a set of bulk uploaded logs,Which organisation owns this property?,Which organisation manages this letting?,What is the needs type?,What is the letting type?,Is this letting a renewal?,What is the tenancy start date?,"What is the rent type? (grouped into SR, IR or AR)",What is the rent type?,Which type of Intermediate Rent is this letting?,Which 'Other' type of Intermediate Rent is this letting?,Is this a London Affordable Rent letting?,What is the tenant code?,What is the property reference?,Has the tenant seen the MHCLG privacy notice?,Is this the first time the property has been let as social housing?,What rent product was the property most recently let as?,What is the reason for the property being vacant?,Is this property new to the social rented sector?,"If known, property's UPRN",Address line 1,Address line 2,Town or City,County,Postcode,The internal value to indicate if the LA was inferred from the postcode,What is the property's local authority?,Local authority code,Is the UPRN known?,UPRN of the address selected,Was the 'No address found' page seen?,Address line 1 input from address matching feature,Postcode input from address matching feature,Address line 1 entered in bulk upload file,Address line 2 entered in bulk upload file,Town or city entered in bulk upload file,County entered in bulk upload file,Postcode entered in bulk upload file,Local authority entered in bulk upload file,What type of unit is the property?,Is the property built or adapted to wheelchair-user standards?,How many bedrooms does the property have?,What is the void date?,Number of days the property was vacant,The following soft validation was confirmed: You told us that the property has been vacant for more than 2 years. This is higher than we would expect.,Were any major repairs carried out during the void period?,What date were any major repairs completed on?,The following soft validation was confirmed: You told us the property has been vacant for 2 years. This is higher than we would expect.,Is this letting in sheltered accommodation?,Is this a joint tenancy?,Is this a starter tenancy?,What is the type of tenancy?,"If 'Other', what is the type of tenancy?",What is the length of the fixed-term tenancy to the nearest year?,How many people live in the household at this letting?,The following soft validation was confirmed: You told us somebody in the household is pregnant. You also told us there are no female tenants living at the property.,"Where household characteristics have a 'Refused' option for some or all of: AGE1-AGE8, SEX1-SEX8, RELAT2-RELAT8, ECSTAT1-ECSTAT8","Type of household 1 = 1 elder; 2 = 2 adults, including elder(s); 3 = 1 adult; 4 = 2 adults; 5 = 1 adult & 1+ children; 6 = 2+ adults & 1+ children; 9 = Other",Total number of dependent children in the household (Sum of when RELAT2-8 = C),Total number of elders in household (Sum of when AGE1-8 >= 60),Total number of adults in household,What is the lead tenant's age?,The following soft validation was confirmed: You told us this person is aged %{age} years and retired. The minimum expected retirement age for %{gender} in England is %{age}.,What was the lead tenant's sex at birth?,Is the gender the lead tenant identifies with the same as their sex registered at birth?,"If 'No', enter the lead tenant's gender identity",What is the lead tenant's ethnic group?,Which of these best describes the lead tenant's ethnic background?,What is the lead tenant's nationality?,Which of these best describes the lead tenant's working situation?,The following soft validation was confirmed: You have said that at least one person's situation is 'Unable to work because of long-term sickness or disability'.,Are the details of tenant 2 known?,What is person 2's age?,What is person 2's relationship to the lead tenant?,The following soft validation was confirmed: You said that more than one person in the household is the partner of the lead tenant. Are you sure this is correct?,What was person 2's sex at birth?,Is the gender person 2 identifies with the same as their sex registered at birth?,"If 'No', enter person 2's gender identity",Which of these best describes person 2's working situation?,Are the details of tenant 3 known?,What is person 3's age?,What is person 3's relationship to the lead tenant?,What was person 3's sex at birth?,Is the gender person 3 identifies with the same as their sex registered at birth?,"If 'No', enter person 3's gender identity",Which of these best describes person 3's working situation?,Are the details of tenant 4 known?,What is person 4's age?,What is person 4's relationship to the lead tenant?,What was person 4's sex at birth?,Is the gender person 4 identifies with the same as their sex registered at birth?,"If 'No', enter person 4's gender identity",Which of these best describes person 4's working situation?,Are the details of tenant 5 known?,What is person 5's age?,What is person 5's relationship to the lead tenant?,What was person 5's sex at birth?,Is the gender person 5 identifies with the same as their sex registered at birth?,"If 'No', enter person 5's gender identity",Which of these best describes person 5's working situation?,Are the details of tenant 6 known?,What is person 6's age?,What is person 6's relationship to the lead tenant?,What was person 6's sex at birth?,Is the gender person 6 identifies with the same as their sex registered at birth?,"If 'No', enter person 6's gender identity",Which of these best describes person 6's working situation?,Are the details of tenant 7 known?,What is person 7's age?,What is person 7's relationship to the lead tenant?,What was person 7's sex at birth?,Is the gender person 7 identifies with the same as their sex registered at birth?,"If 'No', enter person 7's gender identity",Which of these best describes person 7's working situation?,Are the details of tenant 8 known?,What is person 8's age?,What is person 8's relationship to the lead tenant?,What was person 8's sex at birth?,Is the gender person 8 identifies with the same as their sex registered at birth?,"If 'No', enter person 8's gender identity",Which of these best describes person 8's working situation?,Does anybody in the household have links to the UK armed forces?,Is this person still serving in the UK armed forces?,Was this person seriously injured or ill as a result of serving in the UK armed forces?,Is anybody in the household pregnant?,Does anybody in the household have any disabled access needs?,"What access needs do they have? (Fully wheelchair-accessible housing, Level access housing or Wheelchair access to essential rooms)",Disabled access needs a) Fully wheelchair-accessible housing,Disabled access needs b) Wheelchair access to essential rooms,Disabled access needs c) Level access housing,Disabled access needs f) Other disabled access needs,Disabled access needs g) No disabled access needs,Disabled access needs h) Don't know,Do they have any other disabled access needs?,Does anybody in the household have a physical or mental health condition (or other illness) expected to last 12 months or more?,Does this person's condition affect their dexterity?,Does this person's condition affect their learning or understanding or concentrating?,Does this person's condition affect their hearing?,Does this person's condition affect their memory?,Does this person's condition affect their mental health?,Does this person's condition affect their mobility?,Does this person's condition affect them socially or behaviourally?,Does this person's condition affect their stamina or breathing or fatigue?,Does this person's condition affect their vision?,Does this person's condition affect them in another way?,How long has the household continuously lived in the local authority area of the new letting?,How long has the household been on the local authority waiting list for the new letting?,What is the tenant's main reason for the household leaving their last settled home?,"If 'Other', what was the main reason for leaving their last settled home?",The soft validation was confirmed,Where was the household immediately before this letting?,Did the household experience homelessness immediately before this letting?,Previous postcode unknown or previous accommodation was temporary,What is the postcode of the household's last settled home?,Was the local authority of the household's last settled home known?,The internal value to indicate if the previous LA was inferred from the postcode,Previous location LA name,Previous location's ONS LA Code,Was the household given reasonable preference by the local authority?,Reasonable preference reason - They were homeless or about to lose their home (within 56 days),"Reasonable preference reason - They were living in insanitary, overcrowded or unisatisfactory housing",Reasonable preference reason - They needed to move on medical and welfare reasons (including disability),Reasonable preference reason - They needed to move to avoid hardship to themselves or others,Reasonable preference reason - Don't Know,Was the letting made under Choice-Based Lettings (CBL)?,Was the letting made under the Common Allocation Policy (CAP)?,Was the letting made under the Common Housing Register (CHR)?,Was the letting made under the Accessible Register?,"The letting was not allocated under CBL, CAP, CHR or Accessible Register.",What was the source of referral for this letting?,What was the source of referral for this letting?,What was the source of referral for this letting?,Do you know the household's combined income after tax?,Was the household income refused?,How often does the household receive income?,How much income does the household have in total?,Populated when someone hits the soft validation and confirmed in the service,Is the tenant likely to be receiving any of these housing-related benefits?,"Does the tenant receive housing-related benefits? Yes if hb = Universal Credit housing element or Housing benefit, No if hb = Don't Know, Neither, Tenant prefers not to say or blank","How much of the household's income is from Universal Credit, state pensions or benefits?",Does the household pay rent or other charges for the accommodation?,Does the household pay rent or other charges for the accommodation? - flag for when household_charge is answered no,How often does the household pay rent and other charges?,What is the basic rent?,Weekly rent,Populated when the soft validation and confirmed in the service,What is the service charge?,Weekly service charge,What is the personal service charge?,Weekly personal service charge,What is the support charge?,Weekly support charge,Total charge to the tenant,Weekly total charge to the tenant,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,"After the household has received any housing-related benefits, will they still need to pay for rent and charges?",Can you estimate the outstanding amount?,Estimated outstanding amount,Weekly total rent shortfall charge for tenant receiving housing benefit,What scheme does this letting belong to?,"From scheme code, we map to the scheme name",Does the scheme contain confidential information?,"What is this type of scheme? (Direct access hostel), Foyer, Housing for older people or Other supported housing",Is this scheme registered under the Care Standards Act 2000?,Which organisation owns the housing stock for this scheme?,What client group is this scheme intended for?,Does this scheme provide for another client group?,What is the other client group?,What support does this scheme provide?,Intended length of stay,Date scheme was created,Which location is this letting for?,What is the postcode for this location?,What is the name of this location?,How many units are at this location?,What is the most common type of unit at this location?,What are the mobility standards for the majority of the units in this location?,What is the local authority of this postcode?,When did the first property in this location become available under this scheme? -id,status,duplicate_set_id,created_by,assigned_to,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,bulk_upload_id,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,uprn,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,uprn_known,uprn_selection,address_search_value_check,address_line1_input,postcode_full_input,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,unittype_gn,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,sheltered,joint,startertenancy,tenancy,tenancyother,tenancylength,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sexrab1,gender_same_as_sex1,gender_description1,ethnic_group,ethnic,nationality_all,ecstat1,working_situation_illness_check,details_known_2,age2,relat2,multiple_partners_value_check,sexrab2,gender_same_as_sex2,gender_description2,ecstat2,details_known_3,age3,relat3,sexrab3,gender_same_as_sex3,gender_description3,ecstat3,details_known_4,age4,relat4,sexrab4,gender_same_as_sex4,gender_description4,ecstat4,details_known_5,age5,relat5,sexrab5,gender_same_as_sex5,gender_description5,ecstat5,details_known_6,age6,relat6,sexrab6,gender_same_as_sex6,gender_description6,ecstat6,details_known_7,age7,relat7,sexrab7,gender_same_as_sex7,gender_description7,ecstat7,details_known_8,age8,relat8,sexrab8,gender_same_as_sex8,gender_description8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral_register,referral_noms,referral_org,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_confidential,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate -,in_progress,,s.port@jeemayle.com,s.port@jeemayle.com,false,2026-04-01T00:00:00+01:00,,2026-04-01T00:00:00+01:00,1,2026,,MHCLG,MHCLG,1,7,0,2026-04-01,2,2,,,2,HIJKLMN,ABCDEFG,1,0,2,6,2,,Address line 1,,London,,NW9 5LL,false,Barnet,E09000003,0,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,7,1,3,2026-03-30,1,,1,2026-03-31,,,3,1,4,,2,4,,1,4,0,0,2,35,,F,1,,0,2,36,0,,0,32,P,,M,2,Non-binary,6,1,-9,R,R,3,,10,0,-9,R,R,3,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,,6,1,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,0,0,1,,,0,0,1,268,,6,1,1,,,2,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,, +Log ID,Status of log,ID of a set of duplicate logs,User the log is created by,User the log is assigned to,Is the user in the assigned_to column the data protection officer?,Time and date the log was created,User who last updated the log,Time and date the log was last updated,Was the log submitted in-service or via bulk upload?,Year collection period opened,ID of a set of bulk uploaded logs,Which organisation owns this property?,Which organisation manages this letting?,What is the needs type?,What is the letting type?,Is this letting a renewal?,What is the tenancy start date?,"What is the rent type? (grouped into SR, IR or AR)",What is the rent type?,Which type of Intermediate Rent is this letting?,Which 'Other' type of Intermediate Rent is this letting?,Is this a London Affordable Rent letting?,What is the tenant code?,What is the property reference?,Has the tenant seen the MHCLG privacy notice?,Is this the first time the property has been let as social housing?,What rent product was the property most recently let as?,What is the reason for the property being vacant?,Is this property new to the social rented sector?,"If known, property's UPRN",Address line 1,Address line 2,Town or City,County,Postcode,The internal value to indicate if the LA was inferred from the postcode,What is the property's local authority?,Local authority code,Is the UPRN known?,UPRN of the address selected,Was the 'No address found' page seen?,Address line 1 input from address matching feature,Postcode input from address matching feature,Address line 1 entered in bulk upload file,Address line 2 entered in bulk upload file,Town or city entered in bulk upload file,County entered in bulk upload file,Postcode entered in bulk upload file,Local authority entered in bulk upload file,What type of unit is the property?,Is the property built or adapted to wheelchair-user standards?,How many bedrooms does the property have?,What is the void date?,Number of days the property was vacant,The following soft validation was confirmed: You told us that the property has been vacant for more than 2 years. This is higher than we would expect.,Were any major repairs carried out during the void period?,What date were any major repairs completed on?,The following soft validation was confirmed: You told us the property has been vacant for 2 years. This is higher than we would expect.,Is this letting in sheltered accommodation?,Is this a joint tenancy?,Is this a starter tenancy?,What is the type of tenancy?,"If 'Other', what is the type of tenancy?",,What is the length of the fixed-term tenancy to the nearest year?,How many people live in the household at this letting?,The following soft validation was confirmed: You told us somebody in the household is pregnant. You also told us there are no female tenants living at the property.,"Where household characteristics have a 'Refused' option for some or all of: AGE1-AGE8, SEX1-SEX8, RELAT2-RELAT8, ECSTAT1-ECSTAT8","Type of household 1 = 1 elder; 2 = 2 adults, including elder(s); 3 = 1 adult; 4 = 2 adults; 5 = 1 adult & 1+ children; 6 = 2+ adults & 1+ children; 9 = Other",Total number of dependent children in the household (Sum of when RELAT2-8 = C),Total number of elders in household (Sum of when AGE1-8 >= 60),Total number of adults in household,What is the lead tenant's age?,The following soft validation was confirmed: You told us this person is aged %{age} years and retired. The minimum expected retirement age for %{gender} in England is %{age}.,What was the lead tenant's sex at birth?,Is the gender the lead tenant identifies with the same as their sex registered at birth?,"If 'No', enter the lead tenant's gender identity",What is the lead tenant's ethnic group?,Which of these best describes the lead tenant's ethnic background?,What is the lead tenant's nationality?,Which of these best describes the lead tenant's working situation?,The following soft validation was confirmed: You have said that at least one person's situation is 'Unable to work because of long-term sickness or disability'.,Are the details of tenant 2 known?,What is person 2's age?,What is person 2's relationship to the lead tenant?,The following soft validation was confirmed: You said that more than one person in the household is the partner of the lead tenant. Are you sure this is correct?,What was person 2's sex at birth?,Is the gender person 2 identifies with the same as their sex registered at birth?,"If 'No', enter person 2's gender identity",Which of these best describes person 2's working situation?,Are the details of tenant 3 known?,What is person 3's age?,What is person 3's relationship to the lead tenant?,What was person 3's sex at birth?,Is the gender person 3 identifies with the same as their sex registered at birth?,"If 'No', enter person 3's gender identity",Which of these best describes person 3's working situation?,Are the details of tenant 4 known?,What is person 4's age?,What is person 4's relationship to the lead tenant?,What was person 4's sex at birth?,Is the gender person 4 identifies with the same as their sex registered at birth?,"If 'No', enter person 4's gender identity",Which of these best describes person 4's working situation?,Are the details of tenant 5 known?,What is person 5's age?,What is person 5's relationship to the lead tenant?,What was person 5's sex at birth?,Is the gender person 5 identifies with the same as their sex registered at birth?,"If 'No', enter person 5's gender identity",Which of these best describes person 5's working situation?,Are the details of tenant 6 known?,What is person 6's age?,What is person 6's relationship to the lead tenant?,What was person 6's sex at birth?,Is the gender person 6 identifies with the same as their sex registered at birth?,"If 'No', enter person 6's gender identity",Which of these best describes person 6's working situation?,Are the details of tenant 7 known?,What is person 7's age?,What is person 7's relationship to the lead tenant?,What was person 7's sex at birth?,Is the gender person 7 identifies with the same as their sex registered at birth?,"If 'No', enter person 7's gender identity",Which of these best describes person 7's working situation?,Are the details of tenant 8 known?,What is person 8's age?,What is person 8's relationship to the lead tenant?,What was person 8's sex at birth?,Is the gender person 8 identifies with the same as their sex registered at birth?,"If 'No', enter person 8's gender identity",Which of these best describes person 8's working situation?,Does anybody in the household have links to the UK armed forces?,Is this person still serving in the UK armed forces?,Was this person seriously injured or ill as a result of serving in the UK armed forces?,Is anybody in the household pregnant?,Does anybody in the household have any disabled access needs?,"What access needs do they have? (Fully wheelchair-accessible housing, Level access housing or Wheelchair access to essential rooms)",Disabled access needs a) Fully wheelchair-accessible housing,Disabled access needs b) Wheelchair access to essential rooms,Disabled access needs c) Level access housing,Disabled access needs f) Other disabled access needs,Disabled access needs g) No disabled access needs,Disabled access needs h) Don't know,Do they have any other disabled access needs?,Does anybody in the household have a physical or mental health condition (or other illness) expected to last 12 months or more?,Does this person's condition affect their dexterity?,Does this person's condition affect their learning or understanding or concentrating?,Does this person's condition affect their hearing?,Does this person's condition affect their memory?,Does this person's condition affect their mental health?,Does this person's condition affect their mobility?,Does this person's condition affect them socially or behaviourally?,Does this person's condition affect their stamina or breathing or fatigue?,Does this person's condition affect their vision?,Does this person's condition affect them in another way?,How long has the household continuously lived in the local authority area of the new letting?,How long has the household been on the local authority waiting list for the new letting?,What is the tenant's main reason for the household leaving their last settled home?,"If 'Other', what was the main reason for leaving their last settled home?",The soft validation was confirmed,Where was the household immediately before this letting?,Did the household experience homelessness immediately before this letting?,Previous postcode unknown or previous accommodation was temporary,What is the postcode of the household's last settled home?,Was the local authority of the household's last settled home known?,The internal value to indicate if the previous LA was inferred from the postcode,Previous location LA name,Previous location's ONS LA Code,Was the household given reasonable preference by the local authority?,Reasonable preference reason - They were homeless or about to lose their home (within 56 days),"Reasonable preference reason - They were living in insanitary, overcrowded or unisatisfactory housing",Reasonable preference reason - They needed to move on medical and welfare reasons (including disability),Reasonable preference reason - They needed to move to avoid hardship to themselves or others,Reasonable preference reason - Don't Know,Was the letting made under Choice-Based Lettings (CBL)?,Was the letting made under the Common Allocation Policy (CAP)?,Was the letting made under the Common Housing Register (CHR)?,Was the letting made under the Accessible Register?,"The letting was not allocated under CBL, CAP, CHR or Accessible Register.",What was the source of referral for this letting?,What was the source of referral for this letting?,What was the source of referral for this letting?,Do you know the household's combined income after tax?,Was the household income refused?,How often does the household receive income?,How much income does the household have in total?,Populated when someone hits the soft validation and confirmed in the service,Is the tenant likely to be receiving any of these housing-related benefits?,"Does the tenant receive housing-related benefits? Yes if hb = Universal Credit housing element or Housing benefit, No if hb = Don't Know, Neither, Tenant prefers not to say or blank","How much of the household's income is from Universal Credit, state pensions or benefits?",Does the household pay rent or other charges for the accommodation?,Does the household pay rent or other charges for the accommodation? - flag for when household_charge is answered no,How often does the household pay rent and other charges?,What is the basic rent?,Weekly rent,Populated when the soft validation and confirmed in the service,What is the service charge?,Weekly service charge,What is the personal service charge?,Weekly personal service charge,What is the support charge?,Weekly support charge,Total charge to the tenant,Weekly total charge to the tenant,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,"After the household has received any housing-related benefits, will they still need to pay for rent and charges?",Can you estimate the outstanding amount?,Estimated outstanding amount,Weekly total rent shortfall charge for tenant receiving housing benefit,What scheme does this letting belong to?,"From scheme code, we map to the scheme name",Does the scheme contain confidential information?,"What is this type of scheme? (Direct access hostel), Foyer, Housing for older people or Other supported housing",Is this scheme registered under the Care Standards Act 2000?,Which organisation owns the housing stock for this scheme?,What client group is this scheme intended for?,Does this scheme provide for another client group?,What is the other client group?,What support does this scheme provide?,Intended length of stay,Date scheme was created,Which location is this letting for?,What is the postcode for this location?,What is the name of this location?,How many units are at this location?,What is the most common type of unit at this location?,What are the mobility standards for the majority of the units in this location?,What is the local authority of this postcode?,When did the first property in this location become available under this scheme? +id,status,duplicate_set_id,created_by,assigned_to,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,bulk_upload_id,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,uprn,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,uprn_known,uprn_selection,address_search_value_check,address_line1_input,postcode_full_input,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,unittype_gn,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,sheltered,joint,startertenancy,tenancy,tenancyother,tenancyother_value_check,tenancylength,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sexrab1,gender_same_as_sex1,gender_description1,ethnic_group,ethnic,nationality_all,ecstat1,working_situation_illness_check,details_known_2,age2,relat2,multiple_partners_value_check,sexrab2,gender_same_as_sex2,gender_description2,ecstat2,details_known_3,age3,relat3,sexrab3,gender_same_as_sex3,gender_description3,ecstat3,details_known_4,age4,relat4,sexrab4,gender_same_as_sex4,gender_description4,ecstat4,details_known_5,age5,relat5,sexrab5,gender_same_as_sex5,gender_description5,ecstat5,details_known_6,age6,relat6,sexrab6,gender_same_as_sex6,gender_description6,ecstat6,details_known_7,age7,relat7,sexrab7,gender_same_as_sex7,gender_description7,ecstat7,details_known_8,age8,relat8,sexrab8,gender_same_as_sex8,gender_description8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral_register,referral_noms,referral_org,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_confidential,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate +,in_progress,,s.port@jeemayle.com,s.port@jeemayle.com,false,2026-04-01T00:00:00+01:00,,2026-04-01T00:00:00+01:00,1,2026,,MHCLG,MHCLG,1,7,0,2026-04-01,2,2,,,2,HIJKLMN,ABCDEFG,1,0,2,6,2,,Address line 1,,London,,NW9 5LL,false,Barnet,E09000003,0,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,7,1,3,2026-03-30,1,,1,2026-03-31,,,3,1,4,,,2,4,,1,4,0,0,2,35,,F,1,,0,2,36,0,,0,32,P,,M,2,Non-binary,6,1,-9,R,R,3,,10,0,-9,R,R,3,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,,6,1,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,0,0,1,,,0,0,1,268,,6,1,1,,,2,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,, diff --git a/spec/fixtures/files/lettings_log_csv_export_labels_26.csv b/spec/fixtures/files/lettings_log_csv_export_labels_26.csv index 5a24e5c31..eb7cfd35c 100644 --- a/spec/fixtures/files/lettings_log_csv_export_labels_26.csv +++ b/spec/fixtures/files/lettings_log_csv_export_labels_26.csv @@ -1,3 +1,3 @@ -Log ID,Status of log,ID of a set of duplicate logs,User the log is created by,User the log is assigned to,Is the user in the assigned_to column the data protection officer?,Time and date the log was created,User who last updated the log,Time and date the log was last updated,Was the log submitted in-service or via bulk upload?,Year collection period opened,ID of a set of bulk uploaded logs,Which organisation owns this property?,Which organisation manages this letting?,What is the needs type?,What is the letting type?,Is this letting a renewal?,What is the tenancy start date?,"What is the rent type? (grouped into SR, IR or AR)",What is the rent type?,Which type of Intermediate Rent is this letting?,Which 'Other' type of Intermediate Rent is this letting?,Is this a London Affordable Rent letting?,What is the tenant code?,What is the property reference?,Has the tenant seen the MHCLG privacy notice?,Is this the first time the property has been let as social housing?,What rent product was the property most recently let as?,What is the reason for the property being vacant?,Is this property new to the social rented sector?,"If known, property's UPRN",Address line 1,Address line 2,Town or City,County,Postcode,The internal value to indicate if the LA was inferred from the postcode,What is the property's local authority?,Local authority code,Is the UPRN known?,UPRN of the address selected,Was the 'No address found' page seen?,Address line 1 input from address matching feature,Postcode input from address matching feature,Address line 1 entered in bulk upload file,Address line 2 entered in bulk upload file,Town or city entered in bulk upload file,County entered in bulk upload file,Postcode entered in bulk upload file,Local authority entered in bulk upload file,What type of unit is the property?,Is the property built or adapted to wheelchair-user standards?,How many bedrooms does the property have?,What is the void date?,Number of days the property was vacant,The following soft validation was confirmed: You told us that the property has been vacant for more than 2 years. This is higher than we would expect.,Were any major repairs carried out during the void period?,What date were any major repairs completed on?,The following soft validation was confirmed: You told us the property has been vacant for 2 years. This is higher than we would expect.,Is this letting in sheltered accommodation?,Is this a joint tenancy?,Is this a starter tenancy?,What is the type of tenancy?,"If 'Other', what is the type of tenancy?",What is the length of the fixed-term tenancy to the nearest year?,How many people live in the household at this letting?,The following soft validation was confirmed: You told us somebody in the household is pregnant. You also told us there are no female tenants living at the property.,"Where household characteristics have a 'Refused' option for some or all of: AGE1-AGE8, SEX1-SEX8, RELAT2-RELAT8, ECSTAT1-ECSTAT8","Type of household 1 = 1 elder; 2 = 2 adults, including elder(s); 3 = 1 adult; 4 = 2 adults; 5 = 1 adult & 1+ children; 6 = 2+ adults & 1+ children; 9 = Other",Total number of dependent children in the household (Sum of when RELAT2-8 = C),Total number of elders in household (Sum of when AGE1-8 >= 60),Total number of adults in household,What is the lead tenant's age?,The following soft validation was confirmed: You told us this person is aged %{age} years and retired. The minimum expected retirement age for %{gender} in England is %{age}.,What was the lead tenant's sex at birth?,Is the gender the lead tenant identifies with the same as their sex registered at birth?,"If 'No', enter the lead tenant's gender identity",What is the lead tenant's ethnic group?,Which of these best describes the lead tenant's ethnic background?,What is the lead tenant's nationality?,Which of these best describes the lead tenant's working situation?,The following soft validation was confirmed: You have said that at least one person's situation is 'Unable to work because of long-term sickness or disability'.,Are the details of tenant 2 known?,What is person 2's age?,What is person 2's relationship to the lead tenant?,The following soft validation was confirmed: You said that more than one person in the household is the partner of the lead tenant. Are you sure this is correct?,What was person 2's sex at birth?,Is the gender person 2 identifies with the same as their sex registered at birth?,"If 'No', enter person 2's gender identity",Which of these best describes person 2's working situation?,Are the details of tenant 3 known?,What is person 3's age?,What is person 3's relationship to the lead tenant?,What was person 3's sex at birth?,Is the gender person 3 identifies with the same as their sex registered at birth?,"If 'No', enter person 3's gender identity",Which of these best describes person 3's working situation?,Are the details of tenant 4 known?,What is person 4's age?,What is person 4's relationship to the lead tenant?,What was person 4's sex at birth?,Is the gender person 4 identifies with the same as their sex registered at birth?,"If 'No', enter person 4's gender identity",Which of these best describes person 4's working situation?,Are the details of tenant 5 known?,What is person 5's age?,What is person 5's relationship to the lead tenant?,What was person 5's sex at birth?,Is the gender person 5 identifies with the same as their sex registered at birth?,"If 'No', enter person 5's gender identity",Which of these best describes person 5's working situation?,Are the details of tenant 6 known?,What is person 6's age?,What is person 6's relationship to the lead tenant?,What was person 6's sex at birth?,Is the gender person 6 identifies with the same as their sex registered at birth?,"If 'No', enter person 6's gender identity",Which of these best describes person 6's working situation?,Are the details of tenant 7 known?,What is person 7's age?,What is person 7's relationship to the lead tenant?,What was person 7's sex at birth?,Is the gender person 7 identifies with the same as their sex registered at birth?,"If 'No', enter person 7's gender identity",Which of these best describes person 7's working situation?,Are the details of tenant 8 known?,What is person 8's age?,What is person 8's relationship to the lead tenant?,What was person 8's sex at birth?,Is the gender person 8 identifies with the same as their sex registered at birth?,"If 'No', enter person 8's gender identity",Which of these best describes person 8's working situation?,Does anybody in the household have links to the UK armed forces?,Is this person still serving in the UK armed forces?,Was this person seriously injured or ill as a result of serving in the UK armed forces?,Is anybody in the household pregnant?,Does anybody in the household have any disabled access needs?,"What access needs do they have? (Fully wheelchair-accessible housing, Level access housing or Wheelchair access to essential rooms)",Disabled access needs a) Fully wheelchair-accessible housing,Disabled access needs b) Wheelchair access to essential rooms,Disabled access needs c) Level access housing,Disabled access needs f) Other disabled access needs,Disabled access needs g) No disabled access needs,Disabled access needs h) Don't know,Do they have any other disabled access needs?,Does anybody in the household have a physical or mental health condition (or other illness) expected to last 12 months or more?,Does this person's condition affect their dexterity?,Does this person's condition affect their learning or understanding or concentrating?,Does this person's condition affect their hearing?,Does this person's condition affect their memory?,Does this person's condition affect their mental health?,Does this person's condition affect their mobility?,Does this person's condition affect them socially or behaviourally?,Does this person's condition affect their stamina or breathing or fatigue?,Does this person's condition affect their vision?,Does this person's condition affect them in another way?,How long has the household continuously lived in the local authority area of the new letting?,How long has the household been on the local authority waiting list for the new letting?,What is the tenant's main reason for the household leaving their last settled home?,"If 'Other', what was the main reason for leaving their last settled home?",The soft validation was confirmed,Where was the household immediately before this letting?,Did the household experience homelessness immediately before this letting?,Previous postcode unknown or previous accommodation was temporary,What is the postcode of the household's last settled home?,Was the local authority of the household's last settled home known?,The internal value to indicate if the previous LA was inferred from the postcode,Previous location LA name,Previous location's ONS LA Code,Was the household given reasonable preference by the local authority?,Reasonable preference reason - They were homeless or about to lose their home (within 56 days),"Reasonable preference reason - They were living in insanitary, overcrowded or unisatisfactory housing",Reasonable preference reason - They needed to move on medical and welfare reasons (including disability),Reasonable preference reason - They needed to move to avoid hardship to themselves or others,Reasonable preference reason - Don't Know,Was the letting made under Choice-Based Lettings (CBL)?,Was the letting made under the Common Allocation Policy (CAP)?,Was the letting made under the Common Housing Register (CHR)?,Was the letting made under the Accessible Register?,"The letting was not allocated under CBL, CAP, CHR or Accessible Register.",What was the source of referral for this letting?,What was the source of referral for this letting?,What was the source of referral for this letting?,Do you know the household's combined income after tax?,Was the household income refused?,How often does the household receive income?,How much income does the household have in total?,Populated when someone hits the soft validation and confirmed in the service,Is the tenant likely to be receiving any of these housing-related benefits?,"Does the tenant receive housing-related benefits? Yes if hb = Universal Credit housing element or Housing benefit, No if hb = Don't Know, Neither, Tenant prefers not to say or blank","How much of the household's income is from Universal Credit, state pensions or benefits?",Does the household pay rent or other charges for the accommodation?,Does the household pay rent or other charges for the accommodation? - flag for when household_charge is answered no,How often does the household pay rent and other charges?,What is the basic rent?,Weekly rent,Populated when the soft validation and confirmed in the service,What is the service charge?,Weekly service charge,What is the personal service charge?,Weekly personal service charge,What is the support charge?,Weekly support charge,Total charge to the tenant,Weekly total charge to the tenant,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,"After the household has received any housing-related benefits, will they still need to pay for rent and charges?",Can you estimate the outstanding amount?,Estimated outstanding amount,Weekly total rent shortfall charge for tenant receiving housing benefit,What scheme does this letting belong to?,"From scheme code, we map to the scheme name",Does the scheme contain confidential information?,"What is this type of scheme? (Direct access hostel), Foyer, Housing for older people or Other supported housing",Is this scheme registered under the Care Standards Act 2000?,Which organisation owns the housing stock for this scheme?,What client group is this scheme intended for?,Does this scheme provide for another client group?,What is the other client group?,What support does this scheme provide?,Intended length of stay,Date scheme was created,Which location is this letting for?,What is the postcode for this location?,What is the name of this location?,How many units are at this location?,What is the most common type of unit at this location?,What are the mobility standards for the majority of the units in this location?,What is the local authority of this postcode?,When did the first property in this location become available under this scheme? -id,status,duplicate_set_id,created_by,assigned_to,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,bulk_upload_id,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,uprn,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,uprn_known,uprn_selection,address_search_value_check,address_line1_input,postcode_full_input,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,unittype_gn,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,sheltered,joint,startertenancy,tenancy,tenancyother,tenancylength,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sexrab1,gender_same_as_sex1,gender_description1,ethnic_group,ethnic,nationality_all,ecstat1,working_situation_illness_check,details_known_2,age2,relat2,multiple_partners_value_check,sexrab2,gender_same_as_sex2,gender_description2,ecstat2,details_known_3,age3,relat3,sexrab3,gender_same_as_sex3,gender_description3,ecstat3,details_known_4,age4,relat4,sexrab4,gender_same_as_sex4,gender_description4,ecstat4,details_known_5,age5,relat5,sexrab5,gender_same_as_sex5,gender_description5,ecstat5,details_known_6,age6,relat6,sexrab6,gender_same_as_sex6,gender_description6,ecstat6,details_known_7,age7,relat7,sexrab7,gender_same_as_sex7,gender_description7,ecstat7,details_known_8,age8,relat8,sexrab8,gender_same_as_sex8,gender_description8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral_register,referral_noms,referral_org,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_confidential,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate -,in_progress,,s.port@jeemayle.com,s.port@jeemayle.com,false,2026-04-01T00:00:00+01:00,,2026-04-01T00:00:00+01:00,single log,2026,,MHCLG,MHCLG,General needs,Affordable rent general needs local authority,No,2026-04-01,Affordable Rent,Affordable Rent,,,No,HIJKLMN,ABCDEFG,Yes,No,Affordable rent basis,Tenant abandoned property,No,,Address line 1,,London,,NW9 5LL,No,Barnet,E09000003,No,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,House,Yes,3,2026-03-30,1,,Yes,2026-03-31,,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,4,,Yes,4,0,0,2,35,,Female,Yes,,White,Irish,Australia,Other,,Yes,32,Yes,,Male,"No, enter gender identity",Non-binary,Not seeking work,No,Not known,Prefers not to say,Prefers not to say,Prefers not to say,,Prefers not to say,Yes,Not known,Tenant prefers not to say,Prefers not to say,Prefers not to say,,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,,Other supported housing,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,No,Renewal to the same tenant in the same property,,,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,,Every 2 weeks,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,, +Log ID,Status of log,ID of a set of duplicate logs,User the log is created by,User the log is assigned to,Is the user in the assigned_to column the data protection officer?,Time and date the log was created,User who last updated the log,Time and date the log was last updated,Was the log submitted in-service or via bulk upload?,Year collection period opened,ID of a set of bulk uploaded logs,Which organisation owns this property?,Which organisation manages this letting?,What is the needs type?,What is the letting type?,Is this letting a renewal?,What is the tenancy start date?,"What is the rent type? (grouped into SR, IR or AR)",What is the rent type?,Which type of Intermediate Rent is this letting?,Which 'Other' type of Intermediate Rent is this letting?,Is this a London Affordable Rent letting?,What is the tenant code?,What is the property reference?,Has the tenant seen the MHCLG privacy notice?,Is this the first time the property has been let as social housing?,What rent product was the property most recently let as?,What is the reason for the property being vacant?,Is this property new to the social rented sector?,"If known, property's UPRN",Address line 1,Address line 2,Town or City,County,Postcode,The internal value to indicate if the LA was inferred from the postcode,What is the property's local authority?,Local authority code,Is the UPRN known?,UPRN of the address selected,Was the 'No address found' page seen?,Address line 1 input from address matching feature,Postcode input from address matching feature,Address line 1 entered in bulk upload file,Address line 2 entered in bulk upload file,Town or city entered in bulk upload file,County entered in bulk upload file,Postcode entered in bulk upload file,Local authority entered in bulk upload file,What type of unit is the property?,Is the property built or adapted to wheelchair-user standards?,How many bedrooms does the property have?,What is the void date?,Number of days the property was vacant,The following soft validation was confirmed: You told us that the property has been vacant for more than 2 years. This is higher than we would expect.,Were any major repairs carried out during the void period?,What date were any major repairs completed on?,The following soft validation was confirmed: You told us the property has been vacant for 2 years. This is higher than we would expect.,Is this letting in sheltered accommodation?,Is this a joint tenancy?,Is this a starter tenancy?,What is the type of tenancy?,"If 'Other', what is the type of tenancy?",,What is the length of the fixed-term tenancy to the nearest year?,How many people live in the household at this letting?,The following soft validation was confirmed: You told us somebody in the household is pregnant. You also told us there are no female tenants living at the property.,"Where household characteristics have a 'Refused' option for some or all of: AGE1-AGE8, SEX1-SEX8, RELAT2-RELAT8, ECSTAT1-ECSTAT8","Type of household 1 = 1 elder; 2 = 2 adults, including elder(s); 3 = 1 adult; 4 = 2 adults; 5 = 1 adult & 1+ children; 6 = 2+ adults & 1+ children; 9 = Other",Total number of dependent children in the household (Sum of when RELAT2-8 = C),Total number of elders in household (Sum of when AGE1-8 >= 60),Total number of adults in household,What is the lead tenant's age?,The following soft validation was confirmed: You told us this person is aged %{age} years and retired. The minimum expected retirement age for %{gender} in England is %{age}.,What was the lead tenant's sex at birth?,Is the gender the lead tenant identifies with the same as their sex registered at birth?,"If 'No', enter the lead tenant's gender identity",What is the lead tenant's ethnic group?,Which of these best describes the lead tenant's ethnic background?,What is the lead tenant's nationality?,Which of these best describes the lead tenant's working situation?,The following soft validation was confirmed: You have said that at least one person's situation is 'Unable to work because of long-term sickness or disability'.,Are the details of tenant 2 known?,What is person 2's age?,What is person 2's relationship to the lead tenant?,The following soft validation was confirmed: You said that more than one person in the household is the partner of the lead tenant. Are you sure this is correct?,What was person 2's sex at birth?,Is the gender person 2 identifies with the same as their sex registered at birth?,"If 'No', enter person 2's gender identity",Which of these best describes person 2's working situation?,Are the details of tenant 3 known?,What is person 3's age?,What is person 3's relationship to the lead tenant?,What was person 3's sex at birth?,Is the gender person 3 identifies with the same as their sex registered at birth?,"If 'No', enter person 3's gender identity",Which of these best describes person 3's working situation?,Are the details of tenant 4 known?,What is person 4's age?,What is person 4's relationship to the lead tenant?,What was person 4's sex at birth?,Is the gender person 4 identifies with the same as their sex registered at birth?,"If 'No', enter person 4's gender identity",Which of these best describes person 4's working situation?,Are the details of tenant 5 known?,What is person 5's age?,What is person 5's relationship to the lead tenant?,What was person 5's sex at birth?,Is the gender person 5 identifies with the same as their sex registered at birth?,"If 'No', enter person 5's gender identity",Which of these best describes person 5's working situation?,Are the details of tenant 6 known?,What is person 6's age?,What is person 6's relationship to the lead tenant?,What was person 6's sex at birth?,Is the gender person 6 identifies with the same as their sex registered at birth?,"If 'No', enter person 6's gender identity",Which of these best describes person 6's working situation?,Are the details of tenant 7 known?,What is person 7's age?,What is person 7's relationship to the lead tenant?,What was person 7's sex at birth?,Is the gender person 7 identifies with the same as their sex registered at birth?,"If 'No', enter person 7's gender identity",Which of these best describes person 7's working situation?,Are the details of tenant 8 known?,What is person 8's age?,What is person 8's relationship to the lead tenant?,What was person 8's sex at birth?,Is the gender person 8 identifies with the same as their sex registered at birth?,"If 'No', enter person 8's gender identity",Which of these best describes person 8's working situation?,Does anybody in the household have links to the UK armed forces?,Is this person still serving in the UK armed forces?,Was this person seriously injured or ill as a result of serving in the UK armed forces?,Is anybody in the household pregnant?,Does anybody in the household have any disabled access needs?,"What access needs do they have? (Fully wheelchair-accessible housing, Level access housing or Wheelchair access to essential rooms)",Disabled access needs a) Fully wheelchair-accessible housing,Disabled access needs b) Wheelchair access to essential rooms,Disabled access needs c) Level access housing,Disabled access needs f) Other disabled access needs,Disabled access needs g) No disabled access needs,Disabled access needs h) Don't know,Do they have any other disabled access needs?,Does anybody in the household have a physical or mental health condition (or other illness) expected to last 12 months or more?,Does this person's condition affect their dexterity?,Does this person's condition affect their learning or understanding or concentrating?,Does this person's condition affect their hearing?,Does this person's condition affect their memory?,Does this person's condition affect their mental health?,Does this person's condition affect their mobility?,Does this person's condition affect them socially or behaviourally?,Does this person's condition affect their stamina or breathing or fatigue?,Does this person's condition affect their vision?,Does this person's condition affect them in another way?,How long has the household continuously lived in the local authority area of the new letting?,How long has the household been on the local authority waiting list for the new letting?,What is the tenant's main reason for the household leaving their last settled home?,"If 'Other', what was the main reason for leaving their last settled home?",The soft validation was confirmed,Where was the household immediately before this letting?,Did the household experience homelessness immediately before this letting?,Previous postcode unknown or previous accommodation was temporary,What is the postcode of the household's last settled home?,Was the local authority of the household's last settled home known?,The internal value to indicate if the previous LA was inferred from the postcode,Previous location LA name,Previous location's ONS LA Code,Was the household given reasonable preference by the local authority?,Reasonable preference reason - They were homeless or about to lose their home (within 56 days),"Reasonable preference reason - They were living in insanitary, overcrowded or unisatisfactory housing",Reasonable preference reason - They needed to move on medical and welfare reasons (including disability),Reasonable preference reason - They needed to move to avoid hardship to themselves or others,Reasonable preference reason - Don't Know,Was the letting made under Choice-Based Lettings (CBL)?,Was the letting made under the Common Allocation Policy (CAP)?,Was the letting made under the Common Housing Register (CHR)?,Was the letting made under the Accessible Register?,"The letting was not allocated under CBL, CAP, CHR or Accessible Register.",What was the source of referral for this letting?,What was the source of referral for this letting?,What was the source of referral for this letting?,Do you know the household's combined income after tax?,Was the household income refused?,How often does the household receive income?,How much income does the household have in total?,Populated when someone hits the soft validation and confirmed in the service,Is the tenant likely to be receiving any of these housing-related benefits?,"Does the tenant receive housing-related benefits? Yes if hb = Universal Credit housing element or Housing benefit, No if hb = Don't Know, Neither, Tenant prefers not to say or blank","How much of the household's income is from Universal Credit, state pensions or benefits?",Does the household pay rent or other charges for the accommodation?,Does the household pay rent or other charges for the accommodation? - flag for when household_charge is answered no,How often does the household pay rent and other charges?,What is the basic rent?,Weekly rent,Populated when the soft validation and confirmed in the service,What is the service charge?,Weekly service charge,What is the personal service charge?,Weekly personal service charge,What is the support charge?,Weekly support charge,Total charge to the tenant,Weekly total charge to the tenant,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,Populated when the soft validation and confirmed in the service,"After the household has received any housing-related benefits, will they still need to pay for rent and charges?",Can you estimate the outstanding amount?,Estimated outstanding amount,Weekly total rent shortfall charge for tenant receiving housing benefit,What scheme does this letting belong to?,"From scheme code, we map to the scheme name",Does the scheme contain confidential information?,"What is this type of scheme? (Direct access hostel), Foyer, Housing for older people or Other supported housing",Is this scheme registered under the Care Standards Act 2000?,Which organisation owns the housing stock for this scheme?,What client group is this scheme intended for?,Does this scheme provide for another client group?,What is the other client group?,What support does this scheme provide?,Intended length of stay,Date scheme was created,Which location is this letting for?,What is the postcode for this location?,What is the name of this location?,How many units are at this location?,What is the most common type of unit at this location?,What are the mobility standards for the majority of the units in this location?,What is the local authority of this postcode?,When did the first property in this location become available under this scheme? +id,status,duplicate_set_id,created_by,assigned_to,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,bulk_upload_id,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,uprn,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,uprn_known,uprn_selection,address_search_value_check,address_line1_input,postcode_full_input,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,unittype_gn,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,sheltered,joint,startertenancy,tenancy,tenancyother,tenancyother_value_check,tenancylength,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sexrab1,gender_same_as_sex1,gender_description1,ethnic_group,ethnic,nationality_all,ecstat1,working_situation_illness_check,details_known_2,age2,relat2,multiple_partners_value_check,sexrab2,gender_same_as_sex2,gender_description2,ecstat2,details_known_3,age3,relat3,sexrab3,gender_same_as_sex3,gender_description3,ecstat3,details_known_4,age4,relat4,sexrab4,gender_same_as_sex4,gender_description4,ecstat4,details_known_5,age5,relat5,sexrab5,gender_same_as_sex5,gender_description5,ecstat5,details_known_6,age6,relat6,sexrab6,gender_same_as_sex6,gender_description6,ecstat6,details_known_7,age7,relat7,sexrab7,gender_same_as_sex7,gender_description7,ecstat7,details_known_8,age8,relat8,sexrab8,gender_same_as_sex8,gender_description8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral_register,referral_noms,referral_org,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_confidential,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate +,in_progress,,s.port@jeemayle.com,s.port@jeemayle.com,false,2026-04-01T00:00:00+01:00,,2026-04-01T00:00:00+01:00,single log,2026,,MHCLG,MHCLG,General needs,Affordable rent general needs local authority,No,2026-04-01,Affordable Rent,Affordable Rent,,,No,HIJKLMN,ABCDEFG,Yes,No,Affordable rent basis,Tenant abandoned property,No,,Address line 1,,London,,NW9 5LL,No,Barnet,E09000003,No,,,,,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,House,Yes,3,2026-03-30,1,,Yes,2026-03-31,,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,,2,4,,Yes,4,0,0,2,35,,Female,Yes,,White,Irish,Australia,Other,,Yes,32,Yes,,Male,"No, enter gender identity",Non-binary,Not seeking work,No,Not known,Prefers not to say,Prefers not to say,Prefers not to say,,Prefers not to say,Yes,Not known,Tenant prefers not to say,Prefers not to say,Prefers not to say,,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,,Other supported housing,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,No,Renewal to the same tenant in the same property,,,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,,Every 2 weeks,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,, diff --git a/spec/models/form/lettings/subsections/tenancy_information_spec.rb b/spec/models/form/lettings/subsections/tenancy_information_spec.rb index 70663629c..290850cf6 100644 --- a/spec/models/form/lettings/subsections/tenancy_information_spec.rb +++ b/spec/models/form/lettings/subsections/tenancy_information_spec.rb @@ -18,6 +18,7 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do before do allow(form).to receive(:start_year_2024_or_later?).and_return(true) allow(form).to receive(:start_year_2025_or_later?).and_return(false) + allow(form).to receive(:start_year_2026_or_later?).and_return(false) end context "when 2023" do @@ -26,6 +27,7 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do before do allow(form).to receive(:start_year_2024_or_later?).and_return(false) allow(form).to receive(:start_year_2025_or_later?).and_return(false) + allow(form).to receive(:start_year_2026_or_later?).and_return(false) end it "has correct pages" do @@ -41,6 +43,7 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do before do allow(form).to receive(:start_year_2024_or_later?).and_return(true) allow(form).to receive(:start_year_2025_or_later?).and_return(false) + allow(form).to receive(:start_year_2026_or_later?).and_return(false) end it "has correct pages" do @@ -56,6 +59,7 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do before do allow(form).to receive(:start_year_2024_or_later?).and_return(true) allow(form).to receive(:start_year_2025_or_later?).and_return(true) + allow(form).to receive(:start_year_2026_or_later?).and_return(false) end it "has correct pages" do @@ -64,6 +68,22 @@ RSpec.describe Form::Lettings::Subsections::TenancyInformation, type: :model do ) end end + + context "when 2026" do + let(:start_date) { Time.utc(2026, 2, 8) } + + before do + allow(form).to receive(:start_year_2024_or_later?).and_return(true) + allow(form).to receive(:start_year_2025_or_later?).and_return(true) + allow(form).to receive(:start_year_2026_or_later?).and_return(true) + end + + it "has correct pages" do + expect(tenancy_information.pages.map(&:id)).to eq( + %w[joint starter_tenancy tenancy_type starter_tenancy_type tenancyother_value_check tenancy_length tenancy_length_affordable_rent tenancy_length_intermediate_rent tenancy_length_periodic], + ) + end + end end it "has the correct id" do diff --git a/spec/models/validations/soft_validations_spec.rb b/spec/models/validations/soft_validations_spec.rb index 02b383acf..9026b03dc 100644 --- a/spec/models/validations/soft_validations_spec.rb +++ b/spec/models/validations/soft_validations_spec.rb @@ -1535,6 +1535,44 @@ RSpec.describe Validations::SoftValidations do end end + describe "tenancyother_might_be_introductory_or_starter_period?" do + it "returns true if tenancyother is exactly in the 'likely introductory/starter period' list" do + record.tenancyother = "introductory" + + expect(record).to be_tenancyother_might_be_introductory_or_starter_period + end + + it "returns true if any word of tenancyother is exactly in the 'likely introductory/starter period' list" do + record.tenancyother = "a starter tenancy" + + expect(record).to be_tenancyother_might_be_introductory_or_starter_period + end + + it "is not case sensitive when matching" do + record.tenancyother = "Intro" + + expect(record).to be_tenancyother_might_be_introductory_or_starter_period + end + + it "returns false if no part of tenancyother is in the 'likely introductory/starter period' list" do + record.tenancyother = "other" + + expect(record).not_to be_tenancyother_might_be_introductory_or_starter_period + end + + it "returns false if match to the 'likely introductory/starter period' list is only part of a word" do + record.tenancyother = "wasintroductory" + + expect(record).not_to be_tenancyother_might_be_introductory_or_starter_period + end + + it "ignores neighbouring non-alphabet for matching" do + record.tenancyother = "1starter." + + expect(record).to be_tenancyother_might_be_introductory_or_starter_period + end + end + describe "at_least_one_working_situation_is_sickness_and_household_sickness_is_no" do it "returns true if one person has working situation as illness and household sickness is no" do record.illness = 2 From d79cfcd4151f42ebc7916e595e0ea5e4979a43d1 Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Wed, 25 Feb 2026 09:25:19 +0000 Subject: [PATCH 2/2] CLDC-4237: Upgrade ruby version (#3190) * CLDC-4237: Upgrade ruby to 3.4.4 * CLDC-4237: Add additional build dependencies to Dockerfile * CLDC-4237: Update rubocop * CLDC-4237: Fix new rubocop rules most auto applies RSpec/IndexedLet had 200 hits needing manual correction so left these for now * CLDC-4237: Resolve vulnerable dependencies * CLDC-4237: Fix erb files * CLDC-4237: Downgrade connection_pool --- .erb-lint.yml => .erb_lint.yml | 0 .rubocop.yml | 5 + .ruby-version | 2 +- Dockerfile | 4 +- Gemfile | 11 +- Gemfile.lock | 111 ++++++++------ app/controllers/csv_downloads_controller.rb | 2 +- app/controllers/lettings_logs_controller.rb | 2 +- .../lettings_logs_filters_controller.rb | 2 - app/controllers/merge_requests_controller.rb | 2 +- .../sales_logs_filters_controller.rb | 2 - .../bulk_upload/lettings_log_to_csv.rb | 2 - app/helpers/bulk_upload/sales_log_to_csv.rb | 2 - app/helpers/data_sharing_agreement_helper.rb | 2 +- app/helpers/form_page_error_helper.rb | 2 +- app/helpers/locations_helper.rb | 3 +- app/helpers/merge_requests_helper.rb | 4 +- app/helpers/notifications_helper.rb | 4 +- app/helpers/question_view_helper.rb | 3 +- app/helpers/schemes_helper.rb | 3 +- app/mailers/devise_notify_mailer.rb | 3 +- .../lettings_log_variables.rb | 10 +- app/models/derived_variables/shared_logic.rb | 2 +- app/models/form/sales/pages/deposit.rb | 3 +- .../form/sales/questions/deposit_amount.rb | 6 +- .../form/sales/questions/mortgage_amount.rb | 3 +- .../form/sales/questions/mortgageused.rb | 3 +- .../form/sales/questions/purchase_price.rb | 3 +- app/models/form/subsection.rb | 2 +- app/models/lettings_log.rb | 6 +- app/models/sales_log.rb | 2 +- .../sales/sale_information_validations.rb | 2 +- .../validations/sales/soft_validations.rb | 2 +- app/models/validations/shared_validations.rb | 10 +- app/policies/location_policy.rb | 2 +- app/policies/organisation_policy.rb | 2 +- app/policies/scheme_policy.rb | 2 +- .../lettings/year2023/row_parser.rb | 22 ++- .../lettings/year2024/row_parser.rb | 10 +- .../lettings/year2025/row_parser.rb | 10 +- .../lettings/year2026/row_parser.rb | 10 +- .../bulk_upload/sales/year2023/row_parser.rb | 43 ++++-- .../bulk_upload/sales/year2024/row_parser.rb | 40 +++-- .../bulk_upload/sales/year2025/row_parser.rb | 39 +++-- .../bulk_upload/sales/year2026/row_parser.rb | 39 +++-- app/services/csv/lettings_log_csv_service.rb | 6 +- app/services/csv/sales_log_csv_service.rb | 3 +- app/services/documentation_generator.rb | 2 +- .../exports/organisation_export_constants.rb | 2 +- app/services/filter_manager.rb | 2 +- app/views/form/_checkbox_question.html.erb | 2 +- .../_interruption_screen_question.html.erb | 4 +- app/views/form/_radio_question.html.erb | 4 +- .../rails_admin/main/_submit_buttons.html.erb | 2 +- app/views/rails_admin/main/dashboard.html.erb | 2 +- app/views/rails_admin/main/delete.html.erb | 2 +- config/initializers/multi_logger.rb | 8 +- config/initializers/sidekiq.rb | 2 +- config/routes.rb | 4 +- ..._storage_variant_records.active_storage.rb | 2 +- docs/setup.md | 4 +- .../generate_lettings_documentation.rake | 2 +- lib/tasks/generate_sales_documentation.rake | 2 +- lib/tasks/handle_unpended_logs.rake | 4 +- lib/tasks/lint.rake | 2 +- .../set_log_validation_collection_year.rake | 2 +- .../bulk_upload_error_row_component_spec.rb | 2 +- ...nswers_summary_list_card_component_spec.rb | 4 +- .../create_log_actions_component_spec.rb | 16 +- ...tion_confirmation_banner_component_spec.rb | 28 ++-- spec/db/seeds_spec.rb | 3 +- .../factories/data_protection_confirmation.rb | 2 +- spec/features/accessibility_spec.rb | 2 +- .../bulk_upload_lettings_logs_spec.rb | 4 +- spec/features/bulk_upload_sales_logs_spec.rb | 4 +- .../form/accessible_autocomplete_spec.rb | 20 +-- spec/features/form/address_search_spec.rb | 6 +- spec/features/form/checkboxes_spec.rb | 2 +- .../form/conditional_questions_spec.rb | 6 +- spec/features/form/page_routing_spec.rb | 28 ++-- .../form/progressive_total_field_spec.rb | 4 +- spec/features/form/saving_data_spec.rb | 2 +- spec/features/form/validations_spec.rb | 2 +- spec/features/lettings_log_spec.rb | 6 +- spec/features/sales_log_spec.rb | 4 +- spec/features/schemes_spec.rb | 4 +- spec/features/user_spec.rb | 10 +- .../collection_resources_helper_spec.rb | 2 +- .../helpers/question_attribute_helper_spec.rb | 4 +- spec/helpers/tag_helper_spec.rb | 2 +- spec/helpers/tasklist_helper_spec.rb | 8 +- spec/jobs/process_merge_request_job_spec.rb | 4 +- .../tasks/clear_unconfirmed_emails_spec.rb | 4 +- .../local_authority_links_import_spec.rb | 2 +- .../tasks/set_export_collection_years_spec.rb | 4 +- .../set_sales_managing_organisation_spec.rb | 8 +- ...ate_schemes_and_locations_from_csv_spec.rb | 22 +-- spec/mailers/devise_notify_mailer_spec.rb | 5 +- spec/models/bulk_upload_spec.rb | 4 +- .../care_home_charges_value_check_spec.rb | 2 +- .../form/lettings/pages/created_by_spec.rb | 10 +- ...t_household_person_age_value_check_spec.rb | 2 +- ...gnant_household_person_value_check_spec.rb | 2 +- .../pages/managing_organisation_spec.rb | 24 +-- .../multiple_partners_value_check_spec.rb | 2 +- .../lettings/pages/no_address_found_spec.rb | 2 +- ...t_household_person_age_value_check_spec.rb | 2 +- ...gnant_household_person_value_check_spec.rb | 2 +- .../pages/partner_under16_value_check_spec.rb | 2 +- .../form/lettings/pages/person_age_spec.rb | 2 +- .../pages/person_gender_identity_spec.rb | 2 +- .../form/lettings/pages/person_known_spec.rb | 2 +- .../pages/person_lead_partner_spec.rb | 2 +- ...person_over_retirement_value_check_spec.rb | 2 +- .../pages/person_relationship_to_lead_spec.rb | 2 +- ...erson_under_retirement_value_check_spec.rb | 2 +- .../pages/person_working_situation_spec.rb | 2 +- .../lettings/pages/property_reference_spec.rb | 2 +- .../lettings/pages/referral_noms_hr_spec.rb | 2 +- .../pages/referral_noms_la_hr_spec.rb | 2 +- .../referral_org_directly_referred_spec.rb | 2 +- .../pages/referral_org_nominated_spec.rb | 2 +- .../pages/referral_register_la_spec.rb | 2 +- .../pages/referral_register_prp_spec.rb | 2 +- .../form/lettings/pages/renewal_spec.rb | 2 +- .../form/lettings/pages/rent_type_spec.rb | 3 +- .../form/lettings/pages/stock_owner_spec.rb | 16 +- .../lettings/pages/tenancy_start_date_spec.rb | 2 +- .../form/lettings/pages/tenant_code_spec.rb | 2 +- .../lettings/pages/uprn_selection_spec.rb | 2 +- .../address_line1_for_address_matcher_spec.rb | 4 +- .../lettings/questions/address_line2_spec.rb | 2 +- .../lettings/questions/location_id_spec.rb | 4 +- .../questions/net_income_known_spec.rb | 4 +- .../questions/no_address_found_spec.rb | 2 +- .../lettings/questions/person_partner_spec.rb | 4 +- .../questions/person_relationship_spec.rb | 4 +- .../person_working_situation_spec.rb | 4 +- .../postcode_for_address_matcher_spec.rb | 4 +- .../questions/previous_let_type_spec.rb | 3 +- .../form/lettings/questions/reason_spec.rb | 4 +- .../form/lettings/questions/scheme_id_spec.rb | 11 +- .../form/lettings/questions/sheltered_spec.rb | 6 +- .../questions/uprn_confirmation_spec.rb | 6 +- .../lettings/questions/uprn_selection_spec.rb | 6 +- .../form/lettings/questions/waityear_spec.rb | 3 +- .../form/lettings/sections/household_spec.rb | 2 +- .../sections/rent_and_charges_spec.rb | 2 +- .../sections/tenancy_and_property_spec.rb | 2 +- .../household_characteristics_spec.rb | 11 +- .../subsections/household_needs_spec.rb | 6 +- .../subsections/household_situation_spec.rb | 11 +- .../subsections/property_information_spec.rb | 20 +-- .../subsections/tenancy_information_spec.rb | 20 +-- spec/models/form/page_spec.rb | 3 +- .../pages/about_price_value_check_spec.rb | 2 +- .../sales/pages/buyer1_ethnic_group_spec.rb | 8 +- ..._income_discounted_max_value_check_spec.rb | 2 +- .../buyer1_income_ecstat_value_check_spec.rb | 2 +- .../pages/buyer1_live_in_property_spec.rb | 10 +- .../sales/pages/buyer1_nationality_spec.rb | 8 +- .../pages/buyer1_working_situation_spec.rb | 8 +- .../sales/pages/buyer2_ethnic_group_spec.rb | 8 +- ..._income_discounted_max_value_check_spec.rb | 2 +- .../buyer2_income_ecstat_value_check_spec.rb | 2 +- .../pages/buyer2_live_in_property_spec.rb | 10 +- .../sales/pages/buyer2_nationality_spec.rb | 8 +- .../pages/buyer2_working_situation_spec.rb | 8 +- .../pages/buyer_live_in_value_check_spec.rb | 2 +- .../form/sales/pages/buyer_live_spec.rb | 6 +- .../form/sales/pages/buyer_previous_spec.rb | 10 +- .../sales/pages/buyers_organisations_spec.rb | 2 +- .../combined_income_max_value_check_spec.rb | 2 +- .../form/sales/pages/created_by_spec.rb | 2 +- spec/models/form/sales/pages/deposit_spec.rb | 2 +- .../sales/pages/deposit_value_check_spec.rb | 2 +- .../pages/discounted_sale_value_check_spec.rb | 2 +- .../form/sales/pages/extra_borrowing_spec.rb | 2 +- .../sales/pages/handover_date_check_spec.rb | 2 +- .../pages/household_wheelchair_check_spec.rb | 2 +- .../form/sales/pages/joint_purchase_spec.rb | 6 +- .../form/sales/pages/la_nominations_spec.rb | 10 +- .../sales/pages/leasehold_charges_spec.rb | 2 +- .../pages/living_before_purchase_spec.rb | 18 +-- .../sales/pages/managing_organisation_spec.rb | 38 ++--- .../pages/monthly_charges_value_check_spec.rb | 2 +- .../form/sales/pages/mortgage_amount_spec.rb | 2 +- .../form/sales/pages/mortgage_length_spec.rb | 2 +- .../sales/pages/mortgage_value_check_spec.rb | 2 +- .../multiple_partners_value_check_spec.rb | 2 +- .../form/sales/pages/no_address_found_spec.rb | 2 +- .../number_of_others_in_property_spec.rb | 8 +- .../sales/pages/owning_organisation_spec.rb | 18 +-- .../pages/partner_under16_value_check_spec.rb | 2 +- .../percentage_discount_value_check_spec.rb | 2 +- .../pages/person_gender_identity_spec.rb | 2 +- ...rson_student_not_child_value_check_spec.rb | 2 +- .../pages/retirement_value_check_spec.rb | 2 +- .../form/sales/pages/sale_date_check_spec.rb | 2 +- .../sales/pages/savings_value_check_spec.rb | 2 +- .../form/sales/pages/service_charge_spec.rb | 2 +- .../pages/staircase_owned_value_check_spec.rb | 2 +- .../sales/pages/uprn_confirmation_spec.rb | 8 +- .../form/sales/pages/uprn_selection_spec.rb | 2 +- .../address_line1_for_address_matcher_spec.rb | 4 +- .../sales/questions/address_line2_spec.rb | 2 +- .../sales/questions/buyer_previous_spec.rb | 2 +- .../combined_income_value_check_spec.rb | 2 +- .../sales/questions/deposit_amount_spec.rb | 6 +- .../discounted_ownership_type_spec.rb | 6 +- .../sales/questions/extra_borrowing_spec.rb | 2 +- .../sales/questions/housing_benefits_spec.rb | 3 +- .../sales/questions/la_nominations_spec.rb | 2 +- .../form/sales/questions/mortgageused_spec.rb | 8 +- .../sales/questions/no_address_found_spec.rb | 2 +- .../questions/outright_ownership_type_spec.rb | 8 +- .../sales/questions/ownership_scheme_spec.rb | 6 +- .../questions/owning_organisation_id_spec.rb | 8 +- .../postcode_for_address_matcher_spec.rb | 4 +- .../form/sales/questions/prevown_spec.rb | 2 +- .../form/sales/questions/prevshared_spec.rb | 2 +- .../property_local_authority_spec.rb | 6 +- .../form/sales/questions/resale_spec.rb | 2 +- .../sales/questions/staircase_bought_spec.rb | 2 +- .../sales/questions/staircase_count_spec.rb | 2 +- .../questions/staircase_first_time_spec.rb | 2 +- .../questions/staircase_initial_date_spec.rb | 2 +- .../questions/staircase_last_date_spec.rb | 2 +- .../sales/questions/staircase_owned_spec.rb | 2 +- .../staircase_owned_value_check_spec.rb | 2 +- .../sales/questions/staircase_sale_spec.rb | 2 +- .../form/sales/questions/staircase_spec.rb | 2 +- .../sales/questions/uprn_confirmation_spec.rb | 6 +- .../sales/questions/uprn_selection_spec.rb | 6 +- .../discounted_ownership_scheme_spec.rb | 4 +- .../household_characteristics_spec.rb | 24 +-- .../sales/subsections/outright_sale_spec.rb | 14 +- .../subsections/property_information_spec.rb | 9 +- .../form/sales/subsections/setup_spec.rb | 9 +- .../shared_ownership_initial_purchase_spec.rb | 6 +- .../shared_ownership_scheme_spec.rb | 4 +- spec/models/form_spec.rb | 32 ++-- .../bulk_upload_form/upload_your_file_spec.rb | 2 +- .../forms/bulk_upload_form/year_spec.rb | 8 +- spec/models/forms/delete_logs_form_spec.rb | 4 +- .../lettings_log_derived_fields_spec.rb | 16 +- spec/models/lettings_log_spec.rb | 134 ++++++++--------- .../location_deactivation_period_spec.rb | 3 +- spec/models/location_spec.rb | 8 +- spec/models/organisation_spec.rb | 6 +- spec/models/sales_log_spec.rb | 46 +++--- .../models/scheme_deactivation_period_spec.rb | 3 +- spec/models/user_spec.rb | 15 +- .../validations/household_validations_spec.rb | 2 +- .../sale_information_validations_spec.rb | 4 +- spec/presenters/homepage_presenter_spec.rb | 6 +- spec/rails_helper.rb | 2 +- spec/request_helper.rb | 4 +- ...anisations_controller_rent_periods_spec.rb | 2 +- .../address_search_controller_spec.rb | 138 +++++++++--------- spec/requests/check_errors_controller_spec.rb | 24 +-- spec/requests/content_controller_spec.rb | 3 +- spec/requests/cookies_controller_spec.rb | 3 +- spec/requests/delete_logs_controller_spec.rb | 72 ++++----- .../duplicate_logs_controller_spec.rb | 15 +- spec/requests/form_controller_spec.rb | 13 +- .../requests/lettings_logs_controller_spec.rb | 14 +- spec/requests/locations_controller_spec.rb | 42 +++--- spec/requests/maintenance_controller_spec.rb | 3 +- .../merge_requests_controller_spec.rb | 6 +- .../requests/organisations_controller_spec.rb | 24 +-- spec/requests/sales_logs_controller_spec.rb | 8 +- spec/requests/schemes_controller_spec.rb | 116 +++++++-------- spec/requests/users_controller_spec.rb | 8 +- .../bulk_upload/lettings/log_creator_spec.rb | 7 +- .../bulk_upload/lettings/validator_spec.rb | 2 +- .../lettings/year2023/csv_parser_spec.rb | 2 +- .../lettings/year2023/row_parser_spec.rb | 10 +- .../lettings/year2024/csv_parser_spec.rb | 2 +- .../lettings/year2024/row_parser_spec.rb | 16 +- .../lettings/year2025/csv_parser_spec.rb | 2 +- .../lettings/year2025/row_parser_spec.rb | 14 +- .../lettings/year2026/csv_parser_spec.rb | 2 +- .../lettings/year2026/row_parser_spec.rb | 14 +- spec/services/bulk_upload/processor_spec.rb | 25 ++-- .../bulk_upload/sales/log_creator_spec.rb | 7 +- .../bulk_upload/sales/validator_spec.rb | 2 +- .../sales/year2023/csv_parser_spec.rb | 2 +- .../sales/year2023/row_parser_spec.rb | 4 +- .../sales/year2024/csv_parser_spec.rb | 2 +- .../sales/year2024/row_parser_spec.rb | 12 +- .../sales/year2025/csv_parser_spec.rb | 2 +- .../sales/year2025/row_parser_spec.rb | 12 +- .../sales/year2026/csv_parser_spec.rb | 2 +- .../sales/year2026/row_parser_spec.rb | 12 +- .../csv/lettings_log_csv_service_spec.rb | 4 +- .../csv/sales_log_csv_service_spec.rb | 3 +- spec/services/exports/export_service_spec.rb | 90 ++++++------ .../lettings_log_export_service_spec.rb | 4 +- .../merge/merge_organisations_service_spec.rb | 45 +++--- spec/services/storage/s3_service_spec.rb | 3 +- spec/views/form/page_view_spec.rb | 2 +- .../_create_for_org_actions.html.erb_spec.rb | 3 +- 303 files changed, 1250 insertions(+), 1264 deletions(-) rename .erb-lint.yml => .erb_lint.yml (100%) diff --git a/.erb-lint.yml b/.erb_lint.yml similarity index 100% rename from .erb-lint.yml rename to .erb_lint.yml diff --git a/.rubocop.yml b/.rubocop.yml index 7bc65bbd8..4a54015a2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,7 @@ require: - rubocop-performance + +plugins: - rubocop-rails - rubocop-rspec @@ -28,3 +30,6 @@ Rails/UnknownEnv: - development - test - review + +RSpec/IndexedLet: + Enabled: false diff --git a/.ruby-version b/.ruby-version index 9cec7165a..f9892605c 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.6 +3.4.4 diff --git a/Dockerfile b/Dockerfile index 281fd6ca2..88a7e6a79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.1.6-alpine3.20 as base +FROM ruby:3.4.4-alpine3.20 as base WORKDIR /app @@ -10,7 +10,7 @@ RUN apk add --update --no-cache tzdata && \ # build-base: compilation tools for bundle # yarn: node package manager # postgresql-dev: postgres driver and libraries -RUN apk add --no-cache build-base=0.5-r3 busybox=1.36.1-r29 nodejs=20.15.1-r0 yarn=1.22.22-r0 bash=5.2.26-r0 libpq-dev +RUN apk add --no-cache build-base=0.5-r3 busybox=1.36.1-r29 nodejs=20.15.1-r0 yarn=1.22.22-r0 bash=5.2.26-r0 libpq-dev yaml-dev linux-headers # Bundler version should be the same version as what the Gemfile.lock was bundled with RUN gem install bundler:2.6.4 --no-document diff --git a/Gemfile b/Gemfile index f6e7fdac5..91ed6c8a8 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby "3.1.6" +ruby "3.4.4" # Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main' gem "rails", "~> 7.2.2" @@ -51,7 +51,7 @@ gem "paper_trail-globalid" gem "pundit" # Request rate limiting -gem "rack", ">= 2.2.6.3" +gem "rack", "~> 3.1.20" gem "rack-attack" gem "redis", "~> 4.8" # Receive exceptions and configure alerts @@ -72,9 +72,12 @@ gem "sidekiq-cron" gem "unread" # Pinning versions to address vulnerabilities -gem "nokogiri", "~> 1.18.9" +gem "nokogiri", "~> 1.19.1" gem "thor", "~> 1.4.0" +# Pinning until activesupport is updated to v8.1.2 +gem "connection_pool", "~> 2.5" + group :development, :test do # Check gems for known vulnerabilities gem "bundler-audit" @@ -95,7 +98,7 @@ group :development do # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md gem "erb_lint", require: false gem "rack-mini-profiler", "~> 3.3.0" - gem "rubocop-govuk", "4.3.0", require: false + gem "rubocop-govuk", "5.2.0", require: false gem "rubocop-performance", require: false gem "rubocop-rails", require: false end diff --git a/Gemfile.lock b/Gemfile.lock index 34bfd3067..4277b9499 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,7 +78,7 @@ GEM tzinfo (~> 2.0, >= 2.0.5) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - ast (2.4.2) + ast (2.4.3) auto_strip_attributes (2.6.0) activerecord (>= 4.0) aws-eventstream (1.4.0) @@ -113,15 +113,15 @@ GEM thread_safe (~> 0.3, >= 0.3.1) base64 (0.3.0) bcrypt (3.1.20) - benchmark (0.4.1) - better_html (2.0.2) - actionview (>= 6.0) - activesupport (>= 6.0) + benchmark (0.5.0) + better_html (2.2.0) + actionview (>= 7.0) + activesupport (>= 7.0) ast (~> 2.0) erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (3.2.2) + bigdecimal (4.0.1) bindex (0.8.1) bootsnap (1.18.3) msgpack (~> 1.2) @@ -151,7 +151,7 @@ GEM coderay (1.1.3) coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.3.5) + concurrent-ruby (1.3.6) connection_pool (2.5.3) crack (1.0.0) bigdecimal @@ -184,12 +184,12 @@ GEM drb (2.2.3) dumb_delegator (1.0.0) encryptor (3.0.0) - erb_lint (0.5.0) + erb_lint (0.9.0) activesupport better_html (>= 2.0.1) parser (>= 2.7.1.4) rainbow - rubocop + rubocop (>= 1) smart_properties erubi (1.13.1) et-orbi (1.2.11) @@ -232,7 +232,7 @@ GEM hashdiff (1.1.0) html-attributes-utils (1.0.2) activesupport (>= 6.1.4.4) - i18n (1.14.7) + i18n (1.14.8) concurrent-ruby (~> 1.0) ice_nine (0.11.2) iniparse (1.5.0) @@ -261,13 +261,15 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) + language_server-protocol (3.17.0.5) launchy (2.5.2) addressable (~> 2.8) + lint_roller (1.1.0) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) logger (1.7.0) - loofah (2.24.0) + loofah (2.25.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -279,7 +281,9 @@ GEM matrix (0.4.2) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.25.5) + minitest (6.0.2) + drb (~> 2.0) + prism (~> 1.5) msgpack (1.7.2) multipart-post (2.4.1) nested_form (0.3.2) @@ -295,13 +299,13 @@ GEM net-smtp (0.5.1) net-protocol nio4r (2.7.4) - nokogiri (1.18.9-arm64-darwin) + nokogiri (1.19.1-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.9-x86_64-darwin) + nokogiri (1.19.1-x86_64-darwin) racc (~> 1.4) - nokogiri (1.18.9-x86_64-linux-gnu) + nokogiri (1.19.1-x86_64-linux-gnu) racc (~> 1.4) - nokogiri (1.18.9-x86_64-linux-musl) + nokogiri (1.19.1-x86_64-linux-musl) racc (~> 1.4) notifications-ruby-client (6.0.0) jwt (>= 1.5, < 3) @@ -317,10 +321,10 @@ GEM paper_trail-globalid (0.2.0) globalid paper_trail (>= 3.0.0) - parallel (1.24.0) + parallel (1.27.0) parallel_tests (4.5.1) parallel - parser (3.3.0.5) + parser (3.3.10.2) ast (~> 2.4.1) racc pg (1.5.5) @@ -328,6 +332,7 @@ GEM pp (0.6.2) prettyprint prettyprint (0.2.0) + prism (1.9.0) propshaft (0.8.0) actionpack (>= 7.0.0) activesupport (>= 7.0.0) @@ -349,7 +354,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.18) + rack (3.1.20) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-mini-profiler (3.3.1) @@ -375,7 +380,7 @@ GEM activesupport (= 7.2.2.2) bundler (>= 1.15.0) railties (= 7.2.2.2) - rails-dom-testing (2.2.0) + rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) @@ -409,7 +414,7 @@ GEM redis (4.8.1) redis-client (0.22.1) connection_pool - regexp_parser (2.9.0) + regexp_parser (2.11.3) reline (0.6.0) io-console (~> 0.5) request_store (1.7.0) @@ -439,34 +444,45 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.13.1) - rubocop (1.25.0) + rubocop (1.82.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.15.1, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.48.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.15.1) - parser (>= 3.0.1.1) - rubocop-govuk (4.3.0) - rubocop (= 1.25.0) - rubocop-ast (= 1.15.1) - rubocop-rails (= 2.13.2) - rubocop-rake (= 0.6.0) - rubocop-rspec (= 2.7.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + rubocop-capybara (2.22.1) + lint_roller (~> 1.1) + rubocop (~> 1.72, >= 1.72.1) + rubocop-govuk (5.2.0) + rubocop (= 1.82.1) + rubocop-ast (= 1.49.0) + rubocop-capybara (= 2.22.1) + rubocop-rails (= 2.34.3) + rubocop-rake (= 0.7.1) + rubocop-rspec (= 3.9.0) rubocop-performance (1.19.1) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.13.2) + rubocop-rails (2.34.3) activesupport (>= 4.2.0) + lint_roller (~> 1.1) rack (>= 1.1) - rubocop (>= 1.7.0, < 2.0) - rubocop-rake (0.6.0) - rubocop (~> 1.0) - rubocop-rspec (2.7.0) - rubocop (~> 1.19) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + rubocop-rake (0.7.1) + lint_roller (~> 1.1) + rubocop (>= 1.72.1) + rubocop-rspec (3.9.0) + lint_roller (~> 1.1) + rubocop (~> 1.81) ruby-openai (7.0.1) event_stream_parser (>= 0.3.0, < 2.0.0) faraday (>= 1) @@ -514,7 +530,9 @@ GEM tzinfo (2.0.6) concurrent-ruby (~> 1.0) uk_postcode (2.1.8) - unicode-display_width (2.5.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) unread (0.14.0) activerecord (>= 6.1) uri (1.0.4) @@ -563,6 +581,7 @@ DEPENDENCIES capybara capybara-lockstep capybara-screenshot + connection_pool (~> 2.5) cssbundling-rails devise devise_two_factor_authentication @@ -579,7 +598,7 @@ DEPENDENCIES json-schema listen (~> 3.3) method_source (~> 1.1) - nokogiri (~> 1.18.9) + nokogiri (~> 1.19.1) notifications-ruby-client overcommit (>= 0.37.0) paper_trail (~> 15.2) @@ -591,7 +610,7 @@ DEPENDENCIES pry-byebug puma (~> 6.4) pundit - rack (>= 2.2.6.3) + rack (~> 3.1.20) rack-attack rack-mini-profiler (~> 3.3.0) rails (~> 7.2.2) @@ -600,7 +619,7 @@ DEPENDENCIES redis (~> 4.8) roo rspec-rails - rubocop-govuk (= 4.3.0) + rubocop-govuk (= 5.2.0) rubocop-performance rubocop-rails ruby-openai @@ -621,7 +640,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 3.1.6p260 + ruby 3.4.4p0 BUNDLED WITH 2.6.4 diff --git a/app/controllers/csv_downloads_controller.rb b/app/controllers/csv_downloads_controller.rb index 25f70026f..e2a7fb4f1 100644 --- a/app/controllers/csv_downloads_controller.rb +++ b/app/controllers/csv_downloads_controller.rb @@ -5,7 +5,7 @@ class CsvDownloadsController < ApplicationController @csv_download = CsvDownload.find(params[:id]) authorize @csv_download - return render "errors/download_link_expired" if @csv_download.expired? + render "errors/download_link_expired" if @csv_download.expired? end def download diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb index 38a89b682..cd2a6ca5a 100644 --- a/app/controllers/lettings_logs_controller.rb +++ b/app/controllers/lettings_logs_controller.rb @@ -190,7 +190,7 @@ private end def resolve_logs! - if @log&.unresolved && @log.location.present? && @log.scheme.present? && @log&.resolve! + if @log&.unresolved && @log.location.present? && @log.scheme.present? && @log.resolve! unresolved_logs_count_for_user = current_user.lettings_logs.unresolved.assigned_to(current_user).count flash.now[:notice] = helpers.flash_notice_for_resolved_logs(unresolved_logs_count_for_user) end diff --git a/app/controllers/lettings_logs_filters_controller.rb b/app/controllers/lettings_logs_filters_controller.rb index 9180737d3..c6ea0ba70 100644 --- a/app/controllers/lettings_logs_filters_controller.rb +++ b/app/controllers/lettings_logs_filters_controller.rb @@ -52,8 +52,6 @@ class LettingsLogsFiltersController < ApplicationController end end -private - def lettings_session_filters params["years"] = [params["years"]] if params["years"].present? lettings_filter_manager.session_filters diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb index 32f7b2d0c..f1878e9ab 100644 --- a/app/controllers/merge_requests_controller.rb +++ b/app/controllers/merge_requests_controller.rb @@ -105,7 +105,7 @@ private answer_options = { "" => "Select an option" } if current_user.support? - Organisation.all.each do |organisation| + Organisation.all.find_each do |organisation| date = @merge_request.merge_date || Time.zone.today answer_options[organisation.id] = organisation.name(date:) end diff --git a/app/controllers/sales_logs_filters_controller.rb b/app/controllers/sales_logs_filters_controller.rb index ffa4f4bc4..70a4c2b49 100644 --- a/app/controllers/sales_logs_filters_controller.rb +++ b/app/controllers/sales_logs_filters_controller.rb @@ -53,8 +53,6 @@ class SalesLogsFiltersController < ApplicationController end end -private - def sales_session_filters params["years"] = [params["years"]] if params["years"].present? sales_filter_manager.session_filters diff --git a/app/helpers/bulk_upload/lettings_log_to_csv.rb b/app/helpers/bulk_upload/lettings_log_to_csv.rb index 155fb9b12..18a524b0d 100644 --- a/app/helpers/bulk_upload/lettings_log_to_csv.rb +++ b/app/helpers/bulk_upload/lettings_log_to_csv.rb @@ -2,12 +2,10 @@ class BulkUpload::LettingsLogToCsv attr_reader :log, :line_ending, :col_offset, :overrides def initialize(log:, line_ending: "\n", col_offset: 1, overrides: {}) - # rubocop:disable Rails/HelperInstanceVariable @log = log @line_ending = line_ending @col_offset = col_offset @overrides = overrides - # rubocop:enable Rails/HelperInstanceVariable end def row_prefix diff --git a/app/helpers/bulk_upload/sales_log_to_csv.rb b/app/helpers/bulk_upload/sales_log_to_csv.rb index 1171f481f..30833c1c7 100644 --- a/app/helpers/bulk_upload/sales_log_to_csv.rb +++ b/app/helpers/bulk_upload/sales_log_to_csv.rb @@ -2,12 +2,10 @@ class BulkUpload::SalesLogToCsv attr_reader :log, :line_ending, :col_offset, :overrides def initialize(log:, line_ending: "\n", col_offset: 1, overrides: {}) - # rubocop:disable Rails/HelperInstanceVariable @log = log @line_ending = line_ending @col_offset = col_offset @overrides = overrides - # rubocop:enable Rails/HelperInstanceVariable end def row_prefix diff --git a/app/helpers/data_sharing_agreement_helper.rb b/app/helpers/data_sharing_agreement_helper.rb index 79296e6dc..5ab5e3272 100644 --- a/app/helpers/data_sharing_agreement_helper.rb +++ b/app/helpers/data_sharing_agreement_helper.rb @@ -67,7 +67,7 @@ module DataSharingAgreementHelper "12.2. For #{@org_name}: Name: #{@dpo_name}, Postal Address: #{@org_address}, E-mail address: #{@dpo_email}, Telephone number: #{@org_phone}" end end -# rubocop:enable Rails/HelperInstanceVariable + # rubocop:enable Rails/HelperInstanceVariable private diff --git a/app/helpers/form_page_error_helper.rb b/app/helpers/form_page_error_helper.rb index ded09d54c..c2ce87310 100644 --- a/app/helpers/form_page_error_helper.rb +++ b/app/helpers/form_page_error_helper.rb @@ -5,7 +5,7 @@ module FormPageErrorHelper end def remove_duplicate_page_errors(lettings_log) - lettings_log.errors.group_by(&:message).each do |_, errors| + lettings_log.errors.group_by(&:message).each_value do |errors| next if errors.size == 1 errors.shift diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index 9ef74ca51..b8a111b0c 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -91,7 +91,8 @@ module LocationsHelper def toggle_location_link(location) return govuk_button_link_to "Deactivate this location", scheme_location_new_deactivation_path(location.scheme, location), warning: true if location.active? || location.deactivates_in_a_long_time? - return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? && !location.deactivated_by_scheme? + + govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? && !location.deactivated_by_scheme? end def delete_location_link(location) diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 3d9577ce9..6755b4646 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -101,13 +101,13 @@ module MergeRequestsHelper attribute = page if attribute.nil? return nil unless value_exists?(merge_request, attribute) - unless merge_request.status == "request_merged" || merge_request.status == "processing" + unless %w[request_merged processing].include?(merge_request.status) { text: merge_request_action_text(merge_request, attribute), href: send("#{page}_merge_request_path", merge_request, referrer: "check_answers"), visually_hidden_text: page.humanize } end end def merge_outcome_action(merge_request, page) - unless merge_request.status == "request_merged" || merge_request.status == "processing" + unless %w[request_merged processing].include?(merge_request.status) { text: "View", href: send("#{page}_merge_request_path", merge_request), visually_hidden_text: page.humanize } end end diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index 318918134..d3a369b45 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -57,7 +57,7 @@ class NotificationRenderer < Redcarpet::Render::HTML def initialize(options = {}) link_class = "govuk-link" link_class += " govuk-link--inverse" if options[:invert_link_colour] - @bold = options[:bold_all_text] # rubocop:disable Rails/HelperInstanceVariable + @bold = options[:bold_all_text] base_options = { escape_html: true, safe_links_only: true, link_attributes: { class: link_class } } super base_options end @@ -78,7 +78,7 @@ class NotificationRenderer < Redcarpet::Render::HTML end def paragraph(text) - return %(

#{text}

) if @bold # rubocop:disable Rails/HelperInstanceVariable + return %(

#{text}

) if @bold %(

#{text}

) end diff --git a/app/helpers/question_view_helper.rb b/app/helpers/question_view_helper.rb index acb4fa959..0c4b6337f 100644 --- a/app/helpers/question_view_helper.rb +++ b/app/helpers/question_view_helper.rb @@ -44,7 +44,8 @@ module QuestionViewHelper def select_option_name(value) return value.service_name if value.respond_to?(:service_name) return value["name"] if value.is_a?(Hash) && value["name"].present? - return value["postcode"] if value.is_a?(Location) + + value["postcode"] if value.is_a?(Location) end private diff --git a/app/helpers/schemes_helper.rb b/app/helpers/schemes_helper.rb index 753f33917..e72250c6e 100644 --- a/app/helpers/schemes_helper.rb +++ b/app/helpers/schemes_helper.rb @@ -12,7 +12,8 @@ module SchemesHelper def toggle_scheme_link(scheme) return govuk_button_link_to "Deactivate this scheme", scheme_new_deactivation_path(scheme), warning: true if scheme.active? || scheme.deactivates_in_a_long_time? - return govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated? || scheme.deactivating_soon? + + govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated? || scheme.deactivating_soon? end def delete_scheme_link(scheme) diff --git a/app/mailers/devise_notify_mailer.rb b/app/mailers/devise_notify_mailer.rb index 5ee3fd898..4065e3aa9 100644 --- a/app/mailers/devise_notify_mailer.rb +++ b/app/mailers/devise_notify_mailer.rb @@ -92,8 +92,7 @@ class DeviseNotifyMailer < Devise::Mailer def email_changed?(record) ( - record.confirmable_template == User::CONFIRMABLE_TEMPLATE_ID && ( - record.unconfirmed_email.present? && record.unconfirmed_email != record.email) + record.confirmable_template == User::CONFIRMABLE_TEMPLATE_ID && record.unconfirmed_email.present? && record.unconfirmed_email != record.email ) || ( record.versions.last.changeset.key?("unconfirmed_email") && record.confirmed? diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb index 19a58d916..6c88c3221 100644 --- a/app/models/derived_variables/lettings_log_variables.rb +++ b/app/models/derived_variables/lettings_log_variables.rb @@ -254,7 +254,7 @@ private def clear_inapplicable_derived_values! reset_invalidated_derived_values!(dependencies) - if (startdate_changed? || renewal_changed?) && (renewal_was == 1 && startdate_was&.between?(Time.zone.local(2021, 4, 1), Time.zone.local(2022, 3, 31))) + if (startdate_changed? || renewal_changed?) && renewal_was == 1 && startdate_was&.between?(Time.zone.local(2021, 4, 1), Time.zone.local(2022, 3, 31)) self.underoccupation_benefitcap = nil end if renewal_changed? && renewal_was == 1 @@ -270,7 +270,7 @@ private self.wchair = nil self.location_id = nil end - if form.start_year_2024_or_later? && (unittype_gn_changed? && unittype_gn_was == 2) + if form.start_year_2024_or_later? && unittype_gn_changed? && unittype_gn_was == 2 self.beds = nil end end @@ -439,13 +439,15 @@ private def get_lar return 1 if rent_type == 2 - return 2 if rent_type == 1 + + 2 if rent_type == 1 end def get_irproduct return 1 if rent_type == 3 return 2 if rent_type == 4 - return 3 if rent_type == 5 + + 3 if rent_type == 5 end def clear_gender_description_unless_gender_not_same_as_sex! diff --git a/app/models/derived_variables/shared_logic.rb b/app/models/derived_variables/shared_logic.rb index c326cb8c9..4b76d83d8 100644 --- a/app/models/derived_variables/shared_logic.rb +++ b/app/models/derived_variables/shared_logic.rb @@ -9,7 +9,7 @@ private previously_in_derived_state = dependency[:conditions].all? { |attribute, value| send("#{attribute}_was") == value } next unless previously_in_derived_state - dependency[:derived_values].each do |derived_attribute, _derived_value| + dependency[:derived_values].each_key do |derived_attribute| Rails.logger.debug("Cleared derived #{derived_attribute} value") send("#{derived_attribute}=", nil) end diff --git a/app/models/form/sales/pages/deposit.rb b/app/models/form/sales/pages/deposit.rb index 4fc5e1b83..411cfb270 100644 --- a/app/models/form/sales/pages/deposit.rb +++ b/app/models/form/sales/pages/deposit.rb @@ -23,6 +23,7 @@ class Form::Sales::Pages::Deposit < ::Form::Page def copy_key return "sales.sale_information.deposit.shared_ownership" if @ownershipsch == 1 return "sales.sale_information.deposit.discounted_ownership" if @ownershipsch == 2 - return "sales.sale_information.deposit.outright_sale" if @ownershipsch == 3 + + "sales.sale_information.deposit.outright_sale" if @ownershipsch == 3 end end diff --git a/app/models/form/sales/questions/deposit_amount.rb b/app/models/form/sales/questions/deposit_amount.rb index 9fe7a7ce1..ede6335e1 100644 --- a/app/models/form/sales/questions/deposit_amount.rb +++ b/app/models/form/sales/questions/deposit_amount.rb @@ -29,12 +29,14 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question def top_guidance_partial return "financial_calculations_shared_ownership" if @ownershipsch == 1 return "financial_calculations_discounted_ownership" if @ownershipsch == 2 - return "financial_calculations_outright_sale" if @ownershipsch == 3 + + "financial_calculations_outright_sale" if @ownershipsch == 3 end def copy_key return "sales.sale_information.deposit.shared_ownership" if @ownershipsch == 1 return "sales.sale_information.deposit.discounted_ownership" if @ownershipsch == 2 - return "sales.sale_information.deposit.outright_sale" if @ownershipsch == 3 + + "sales.sale_information.deposit.outright_sale" if @ownershipsch == 3 end end diff --git a/app/models/form/sales/questions/mortgage_amount.rb b/app/models/form/sales/questions/mortgage_amount.rb index 0d2bda4fd..a61dce8f3 100644 --- a/app/models/form/sales/questions/mortgage_amount.rb +++ b/app/models/form/sales/questions/mortgage_amount.rb @@ -26,6 +26,7 @@ class Form::Sales::Questions::MortgageAmount < ::Form::Question def top_guidance_partial return "financial_calculations_shared_ownership" if @ownershipsch == 1 return "financial_calculations_discounted_ownership" if @ownershipsch == 2 - return "financial_calculations_outright_sale" if @ownershipsch == 3 + + "financial_calculations_outright_sale" if @ownershipsch == 3 end end diff --git a/app/models/form/sales/questions/mortgageused.rb b/app/models/form/sales/questions/mortgageused.rb index a0079b1b4..fc5818886 100644 --- a/app/models/form/sales/questions/mortgageused.rb +++ b/app/models/form/sales/questions/mortgageused.rb @@ -41,6 +41,7 @@ class Form::Sales::Questions::Mortgageused < ::Form::Question def top_guidance_partial return "financial_calculations_shared_ownership" if @ownershipsch == 1 return "financial_calculations_discounted_ownership" if @ownershipsch == 2 - return "financial_calculations_outright_sale" if @ownershipsch == 3 + + "financial_calculations_outright_sale" if @ownershipsch == 3 end end diff --git a/app/models/form/sales/questions/purchase_price.rb b/app/models/form/sales/questions/purchase_price.rb index 56810eae4..d37d549ce 100644 --- a/app/models/form/sales/questions/purchase_price.rb +++ b/app/models/form/sales/questions/purchase_price.rb @@ -30,6 +30,7 @@ class Form::Sales::Questions::PurchasePrice < ::Form::Question def top_guidance_partial return "financial_calculations_discounted_ownership" if @ownership_sch == 2 - return "financial_calculations_outright_sale" if @ownership_sch == 3 + + "financial_calculations_outright_sale" if @ownership_sch == 3 end end diff --git a/app/models/form/subsection.rb b/app/models/form/subsection.rb index 3b74e29a5..41431b06f 100644 --- a/app/models/form/subsection.rb +++ b/app/models/form/subsection.rb @@ -1,5 +1,5 @@ class Form::Subsection - attr_accessor :id, :label, :section, :pages, :depends_on, :form + attr_accessor :id, :label, :section, :pages, :depends_on def initialize(id, hsh, section) @id = id diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index c3b72fbdd..d70d0e012 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -482,7 +482,7 @@ class LettingsLog < Log def is_london_rent? # 2: London Affordable Rent # 4: London Living Rent - rent_type == 2 || rent_type == 4 + [2, 4].include?(rent_type) end def previous_tenancy_was_foster_care? @@ -714,7 +714,7 @@ class LettingsLog < Log end def affordable_or_social_rent? - renttype == 1 || renttype == 2 + [1, 2].include?(renttype) end def no_or_unknown_other_housing_needs? @@ -931,7 +931,7 @@ private num_of_weeks = NUM_OF_WEEKS_FROM_PERIOD[period] return "" unless value && num_of_weeks - format_as_currency((value * 52 / num_of_weeks)) + format_as_currency(value * 52 / num_of_weeks) end def fully_wheelchair_accessible? diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index d4d23f44d..cf9e0dd44 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -533,7 +533,7 @@ class SalesLog < Log end def is_not_staircasing? - staircase == 2 || staircase == 3 + [2, 3].include?(staircase) end def stairowned_100? diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index f34eec790..063c16599 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -136,7 +136,7 @@ module Validations::Sales::SaleInformationValidations def validate_grant_amount(record) return unless record.saledate && record.form.start_year_2024_or_later? - return unless record.grant && (record.type == 8 || record.type == 21) + return unless record.grant && [8, 21].include?(record.type) unless record.grant.between?(9_000, 16_000) record.errors.add :grant, I18n.t("validations.sales.sale_information.grant.out_of_range") diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index 2bc574774..3569c379f 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -144,7 +144,7 @@ module Validations::Sales::SoftValidations def grant_outside_common_range? return unless grant && type && saledate - return if form.start_year_2024_or_later? && (type == 21 || type == 8) + return if form.start_year_2024_or_later? && [21, 8].include?(type) !grant.between?(9_000, 16_000) end diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb index 530735213..4558a5a36 100644 --- a/app/models/validations/shared_validations.rb +++ b/app/models/validations/shared_validations.rb @@ -56,11 +56,11 @@ module Validations::SharedValidations next unless incorrect_accuracy - case question.step - when 0.01 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:) - when 0.1 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_tenth", field:) - when 1 then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:) - when 10 then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:) + case question.step.to_d + when BigDecimal("0.01") then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_hundredth", field:) + when BigDecimal("0.1") then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_tenth", field:) + when BigDecimal("1") then record.errors.add question.id.to_sym, :not_integer, message: I18n.t("validations.shared.numeric.whole_number", field:) + when BigDecimal("10") then record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_ten", field:) else record.errors.add question.id.to_sym, I18n.t("validations.shared.numeric.nearest_step", field:, step: question.step) end diff --git a/app/policies/location_policy.rb b/app/policies/location_policy.rb index 3b4a22131..966cfe35c 100644 --- a/app/policies/location_policy.rb +++ b/app/policies/location_policy.rb @@ -32,7 +32,7 @@ class LocationPolicy def delete? return false unless user.support? - return false unless location.status == :incomplete || location.status == :deactivated + return false unless %i[incomplete deactivated].include?(location.status) !has_any_logs_in_editable_collection_period end diff --git a/app/policies/organisation_policy.rb b/app/policies/organisation_policy.rb index 9c5fc4449..4db37b5ea 100644 --- a/app/policies/organisation_policy.rb +++ b/app/policies/organisation_policy.rb @@ -20,7 +20,7 @@ class OrganisationPolicy def delete? return false unless user.support? - return false unless organisation.status == :deactivated || organisation.status == :merged + return false unless %i[deactivated merged].include?(organisation.status) !has_any_logs_in_editable_collection_period end diff --git a/app/policies/scheme_policy.rb b/app/policies/scheme_policy.rb index 54a2b9e89..6fa9ac95a 100644 --- a/app/policies/scheme_policy.rb +++ b/app/policies/scheme_policy.rb @@ -71,7 +71,7 @@ class SchemePolicy def delete? return false unless user.support? - return false unless scheme.status == :incomplete || scheme.status == :deactivated + return false unless %i[incomplete deactivated].include?(scheme.status) !has_any_logs_in_editable_collection_period end diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb index 70aa4951e..1e8b9db56 100644 --- a/app/services/bulk_upload/lettings/year2023/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb @@ -536,7 +536,7 @@ private end def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next unless question&.type == "radio" @@ -1321,22 +1321,26 @@ private def scheme_field return :field_16 if log_uses_new_scheme_id? - return :field_15 if log_uses_old_scheme_id? + + :field_15 if log_uses_old_scheme_id? end def scheme_id return field_16.strip if log_uses_new_scheme_id? - return field_15 if log_uses_old_scheme_id? + + field_15 if log_uses_old_scheme_id? end def location_field return :field_17 if log_uses_new_scheme_id? - return :field_16 if log_uses_old_scheme_id? + + :field_16 if log_uses_old_scheme_id? end def location_id return field_17 if log_uses_new_scheme_id? - return field_16 if log_uses_old_scheme_id? + + field_16 if log_uses_old_scheme_id? end def scheme_or_management_group @@ -1424,7 +1428,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1488,7 +1493,8 @@ private def housingneeds_other return 1 if field_86 == 1 - return 0 if [field_83, field_84, field_85].include?(1) + + 0 if [field_83, field_84, field_85].include?(1) end def prevloc @@ -1555,7 +1561,7 @@ private end def earnings - field_122.round if field_122.present? + field_122.presence&.round end def tshortfall_known diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb index 66d46ead5..1ba683f66 100644 --- a/app/services/bulk_upload/lettings/year2024/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb @@ -562,7 +562,7 @@ class BulkUpload::Lettings::Year2024::RowParser private def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next unless question&.type == "radio" @@ -1455,7 +1455,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1519,7 +1520,8 @@ private def housingneeds_other return 1 if field_82 == 1 - return 0 if [field_79, field_80, field_81].include?(1) + + 0 if [field_79, field_80, field_81].include?(1) end def prevloc @@ -1595,7 +1597,7 @@ private end def earnings - field_119.round if field_119.present? + field_119.presence&.round end def tshortfall_known diff --git a/app/services/bulk_upload/lettings/year2025/row_parser.rb b/app/services/bulk_upload/lettings/year2025/row_parser.rb index 0745056d2..9887c42be 100644 --- a/app/services/bulk_upload/lettings/year2025/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2025/row_parser.rb @@ -561,7 +561,7 @@ class BulkUpload::Lettings::Year2025::RowParser private def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next unless question&.type == "radio" @@ -1452,7 +1452,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1516,7 +1517,8 @@ private def housingneeds_other return 1 if field_82 == 1 - return 0 if [field_79, field_80, field_81].include?(1) + + 0 if [field_79, field_80, field_81].include?(1) end def prevloc @@ -1592,7 +1594,7 @@ private end def earnings - field_119.round if field_119.present? + field_119.presence&.round end def tshortfall_known diff --git a/app/services/bulk_upload/lettings/year2026/row_parser.rb b/app/services/bulk_upload/lettings/year2026/row_parser.rb index b73bf792a..c8fc4c891 100644 --- a/app/services/bulk_upload/lettings/year2026/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2026/row_parser.rb @@ -606,7 +606,7 @@ class BulkUpload::Lettings::Year2026::RowParser private def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next unless question&.type == "radio" @@ -1573,7 +1573,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1637,7 +1638,8 @@ private def housingneeds_other return 1 if field_82 == 1 - return 0 if [field_79, field_80, field_81].include?(1) + + 0 if [field_79, field_80, field_81].include?(1) end def prevloc @@ -1713,7 +1715,7 @@ private end def earnings - field_119.round if field_119.present? + field_119.presence&.round end def tshortfall_known diff --git a/app/services/bulk_upload/sales/year2023/row_parser.rb b/app/services/bulk_upload/sales/year2023/row_parser.rb index ddcf18b6a..75f964e7c 100644 --- a/app/services/bulk_upload/sales/year2023/row_parser.rb +++ b/app/services/bulk_upload/sales/year2023/row_parser.rb @@ -915,7 +915,7 @@ private attributes["mortlen"] = mortlen attributes["proplen"] = proplen if proplen&.positive? - attributes["proplen_asked"] = attributes["proplen"]&.present? ? 0 : 1 + attributes["proplen_asked"] = attributes["proplen"].present? ? 0 : 1 attributes["jointmore"] = field_15 attributes["staircase"] = field_87 attributes["privacynotice"] = field_29 @@ -992,7 +992,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1050,72 +1051,84 @@ private def sale_type return field_8 if shared_ownership? return field_9 if discounted_ownership? - return field_10 if outright_sale? + + field_10 if outright_sale? end def value return field_103 if shared_ownership? return field_116 if discounted_ownership? - return field_127 if outright_sale? + + field_127 if outright_sale? end def mortgage return field_106 if shared_ownership? return field_120 if discounted_ownership? - return field_129 if outright_sale? + + field_129 if outright_sale? end def extrabor return field_110 if shared_ownership? return field_124 if discounted_ownership? - return field_133 if outright_sale? + + field_133 if outright_sale? end def deposit return field_111 if shared_ownership? return field_125 if discounted_ownership? - return field_134 if outright_sale? + + field_134 if outright_sale? end def mscharge return field_114 if shared_ownership? return field_126 if discounted_ownership? - return field_135 if outright_sale? + + field_135 if outright_sale? end def mortgagelender return field_107 if shared_ownership? return field_121 if discounted_ownership? - return field_130 if outright_sale? + + field_130 if outright_sale? end def mortgagelenderother return field_108 if shared_ownership? return field_122 if discounted_ownership? - return field_131 if outright_sale? + + field_131 if outright_sale? end def mortlen return field_109 if shared_ownership? return field_123 if discounted_ownership? - return field_132 if outright_sale? + + field_132 if outright_sale? end def proplen return field_86 if shared_ownership? - return field_115 if discounted_ownership? + + field_115 if discounted_ownership? end def mortgageused return field_105 if shared_ownership? return field_119 if discounted_ownership? - return field_128 if outright_sale? + + field_128 if outright_sale? end def mortgageused_field return :field_105 if shared_ownership? return :field_119 if discounted_ownership? - return :field_128 if outright_sale? + + :field_128 if outright_sale? end def owning_organisation @@ -1263,7 +1276,7 @@ private end def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next if question_id == "type" diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index a1b214182..879bdbb3f 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -938,7 +938,7 @@ private attributes["mortlen"] = mortlen attributes["proplen"] = proplen if proplen&.positive? - attributes["proplen_asked"] = attributes["proplen"]&.present? ? 0 : 1 + attributes["proplen_asked"] = attributes["proplen"].present? ? 0 : 1 attributes["jointmore"] = field_16 attributes["staircase"] = field_86 attributes["privacynotice"] = field_18 @@ -1026,7 +1026,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1084,64 +1085,75 @@ private def sale_type return field_9 if shared_ownership? return field_10 if discounted_ownership? - return field_11 if outright_sale? + + field_11 if outright_sale? end def value return field_101 if shared_ownership? return field_114 if discounted_ownership? - return field_125 if outright_sale? + + field_125 if outright_sale? end def mortgage return field_104 if shared_ownership? return field_118 if discounted_ownership? - return field_127 if outright_sale? + + field_127 if outright_sale? end def extrabor return field_108 if shared_ownership? return field_122 if discounted_ownership? - return field_129 if outright_sale? + + field_129 if outright_sale? end def deposit return field_109 if shared_ownership? return field_123 if discounted_ownership? - return field_130 if outright_sale? + + field_130 if outright_sale? end def mscharge return field_112 if shared_ownership? return field_124 if discounted_ownership? - return field_131 if outright_sale? + + field_131 if outright_sale? end def mortgagelender return field_105 if shared_ownership? - return field_119 if discounted_ownership? + + field_119 if discounted_ownership? end def mortgagelenderother return field_106 if shared_ownership? - return field_120 if discounted_ownership? + + field_120 if discounted_ownership? end def mortlen return field_107 if shared_ownership? return field_121 if discounted_ownership? - return field_128 if outright_sale? + + field_128 if outright_sale? end def proplen return field_85 if shared_ownership? - return field_113 if discounted_ownership? + + field_113 if discounted_ownership? end def mortgageused return field_103 if shared_ownership? return field_117 if discounted_ownership? - return field_126 if outright_sale? + + field_126 if outright_sale? end def value_fields @@ -1393,7 +1405,7 @@ private end def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next if question_id == "type" diff --git a/app/services/bulk_upload/sales/year2025/row_parser.rb b/app/services/bulk_upload/sales/year2025/row_parser.rb index a78b9fe5d..19094f6c6 100644 --- a/app/services/bulk_upload/sales/year2025/row_parser.rb +++ b/app/services/bulk_upload/sales/year2025/row_parser.rb @@ -906,7 +906,7 @@ private attributes["mortlen"] = mortlen attributes["proplen"] = proplen if proplen&.positive? - attributes["proplen_asked"] = attributes["proplen"]&.present? ? 0 : 1 + attributes["proplen_asked"] = attributes["proplen"].present? ? 0 : 1 attributes["jointmore"] = field_13 attributes["staircase"] = field_10 attributes["privacynotice"] = field_15 @@ -1008,7 +1008,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1076,58 +1077,68 @@ private def sale_type return field_9 if shared_ownership? - return field_11 if discounted_ownership? + + field_11 if discounted_ownership? end def value return field_86 if shared_ownership_initial_purchase? return field_113 if discounted_ownership? - return field_107 if staircasing? + + field_107 if staircasing? end def equity return field_87 if shared_ownership_initial_purchase? - return field_108 if staircasing? + + field_108 if staircasing? end def mortgage return field_89 if shared_ownership? - return field_117 if discounted_ownership? + + field_117 if discounted_ownership? end def extrabor - return field_119 if discounted_ownership? + field_119 if discounted_ownership? end def deposit return field_91 if shared_ownership? - return field_120 if discounted_ownership? + + field_120 if discounted_ownership? end def mrent return field_93 if shared_ownership_initial_purchase? - return field_111 if staircasing? + + field_111 if staircasing? end def mscharge return field_94 if shared_ownership? - return field_121 if discounted_ownership? + + field_121 if discounted_ownership? end def mortlen return field_90 if shared_ownership? - return field_118 if discounted_ownership? + + field_118 if discounted_ownership? end def proplen return field_79 if shared_ownership? - return field_112 if discounted_ownership? + + field_112 if discounted_ownership? end def mortgageused return field_88 if shared_ownership_initial_purchase? return field_116 if discounted_ownership? - return field_109 if staircasing? + + field_109 if staircasing? end def value_fields @@ -1369,7 +1380,7 @@ private end def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next if question_id == "type" diff --git a/app/services/bulk_upload/sales/year2026/row_parser.rb b/app/services/bulk_upload/sales/year2026/row_parser.rb index adb7cc6a2..08d56fe37 100644 --- a/app/services/bulk_upload/sales/year2026/row_parser.rb +++ b/app/services/bulk_upload/sales/year2026/row_parser.rb @@ -934,7 +934,7 @@ private attributes["mortlen"] = mortlen attributes["proplen"] = proplen if proplen&.positive? - attributes["proplen_asked"] = attributes["proplen"]&.present? ? 0 : 1 + attributes["proplen_asked"] = attributes["proplen"].present? ? 0 : 1 attributes["jointmore"] = field_13 attributes["staircase"] = field_10 attributes["privacynotice"] = field_15 @@ -1036,7 +1036,8 @@ private ].each do |hash| define_method("age#{hash[:person]}_known?") do return 1 if public_send(hash[:field]) == "R" - return 0 if send("person_#{hash[:person]}_present?") + + 0 if send("person_#{hash[:person]}_present?") end end @@ -1104,58 +1105,68 @@ private def sale_type return field_9 if shared_ownership? - return field_11 if discounted_ownership? + + field_11 if discounted_ownership? end def value return field_86 if shared_ownership_initial_purchase? return field_113 if discounted_ownership? - return field_107 if staircasing? + + field_107 if staircasing? end def equity return field_87 if shared_ownership_initial_purchase? - return field_108 if staircasing? + + field_108 if staircasing? end def mortgage return field_89 if shared_ownership? - return field_117 if discounted_ownership? + + field_117 if discounted_ownership? end def extrabor - return field_119 if discounted_ownership? + field_119 if discounted_ownership? end def deposit return field_91 if shared_ownership? - return field_120 if discounted_ownership? + + field_120 if discounted_ownership? end def mrent return field_93 if shared_ownership_initial_purchase? - return field_111 if staircasing? + + field_111 if staircasing? end def mscharge return field_94 if shared_ownership? - return field_121 if discounted_ownership? + + field_121 if discounted_ownership? end def mortlen return field_90 if shared_ownership? - return field_118 if discounted_ownership? + + field_118 if discounted_ownership? end def proplen return field_79 if shared_ownership? - return field_112 if discounted_ownership? + + field_112 if discounted_ownership? end def mortgageused return field_88 if shared_ownership_initial_purchase? return field_116 if discounted_ownership? - return field_109 if staircasing? + + field_109 if staircasing? end def value_fields @@ -1398,7 +1409,7 @@ private end def validate_valid_radio_option - log.attributes.each do |question_id, _v| + log.attributes.each_key do |question_id| question = log.form.get_question(question_id, log) next if question_id == "type" diff --git a/app/services/csv/lettings_log_csv_service.rb b/app/services/csv/lettings_log_csv_service.rb index 003515ac9..dd3be8595 100644 --- a/app/services/csv/lettings_log_csv_service.rb +++ b/app/services/csv/lettings_log_csv_service.rb @@ -398,12 +398,14 @@ module Csv def label_if_boolean_value(value) return "Yes" if value == true - return "No" if value == false + + "No" if value == false end def conventional_yes_no_label(value) return "Yes" if value == 1 - return "No" if value&.zero? + + "No" if value&.zero? end end end diff --git a/app/services/csv/sales_log_csv_service.rb b/app/services/csv/sales_log_csv_service.rb index ed16653f1..07ccad82c 100644 --- a/app/services/csv/sales_log_csv_service.rb +++ b/app/services/csv/sales_log_csv_service.rb @@ -408,7 +408,8 @@ module Csv def label_if_boolean_value(value) return "Yes" if value == true - return "No" if value == false + + "No" if value == false end end end diff --git a/app/services/documentation_generator.rb b/app/services/documentation_generator.rb index c2005f320..58c2031f7 100644 --- a/app/services/documentation_generator.rb +++ b/app/services/documentation_generator.rb @@ -93,7 +93,7 @@ class DocumentationGenerator interruption_screen_pages = form.pages.select { |page| page.questions.first.type == "interruption_screen" } interruption_screen_pages_grouped_by_question = interruption_screen_pages.group_by { |page| page.questions.first.id } - interruption_screen_pages_grouped_by_question.each do |_question_id, pages| + interruption_screen_pages_grouped_by_question.each_value do |pages| pages.map do |page| save_soft_validation(form, page, validation_descriptions, log_type) end diff --git a/app/services/exports/organisation_export_constants.rb b/app/services/exports/organisation_export_constants.rb index 6c78a55db..7ffbfd223 100644 --- a/app/services/exports/organisation_export_constants.rb +++ b/app/services/exports/organisation_export_constants.rb @@ -23,6 +23,6 @@ module Exports::OrganisationExportConstants "dpo_email", "profit_status", "group", - "status" + "status", ] end diff --git a/app/services/filter_manager.rb b/app/services/filter_manager.rb index 7757ad39e..69e895809 100644 --- a/app/services/filter_manager.rb +++ b/app/services/filter_manager.rb @@ -121,7 +121,7 @@ class FilterManager new_filters = new_filters.except("user") if params["assigned_to"] == "all" new_filters["user"] = current_user.id.to_s if params["assigned_to"] == "you" - new_filters = new_filters.except("user_text_search") if params["assigned_to"] == "all" || params["assigned_to"] == "you" + new_filters = new_filters.except("user_text_search") if %w[all you].include?(params["assigned_to"]) new_filters = new_filters.except("owning_organisation_text_search") if params["owning_organisation_select"] == "all" new_filters = new_filters.except("managing_organisation_text_search") if params["managing_organisation_select"] == "all" end diff --git a/app/views/form/_checkbox_question.html.erb b/app/views/form/_checkbox_question.html.erb index b4feb12bd..d3c52c270 100644 --- a/app/views/form/_checkbox_question.html.erb +++ b/app/views/form/_checkbox_question.html.erb @@ -16,7 +16,7 @@ hint: { text: option["hint"] }, checked: @log[key] == 1, exclusive: after_divider, - link_errors: index.zero? ? true : nil, + link_errors: index.zero? || nil, **stimulus_html_attributes(question) %> <% end %> <% end %> diff --git a/app/views/form/_interruption_screen_question.html.erb b/app/views/form/_interruption_screen_question.html.erb index c0063e477..9aa38ca5d 100644 --- a/app/views/form/_interruption_screen_question.html.erb +++ b/app/views/form/_interruption_screen_question.html.erb @@ -18,7 +18,7 @@
<%= f.govuk_submit "Confirm and continue" %> <%= govuk_link_to( - (@page.skip_text || "Skip for now"), - (@page.skip_href(@log) || send(@log.form.next_page_redirect_path(@page, @log, current_user, ignore_answered: true), @log)), + @page.skip_text || "Skip for now", + @page.skip_href(@log) || send(@log.form.next_page_redirect_path(@page, @log, current_user, ignore_answered: true), @log), ) %>
diff --git a/app/views/form/_radio_question.html.erb b/app/views/form/_radio_question.html.erb index bf6abb0d0..e810d7b7a 100644 --- a/app/views/form/_radio_question.html.erb +++ b/app/views/form/_radio_question.html.erb @@ -28,14 +28,14 @@ key, label: { text: options["value"] }, hint: { text: options["hint"] }, - link_errors: index.zero? ? true : nil, + link_errors: index.zero? || nil, **stimulus_html_attributes(question) %> <% else %> <%= f.govuk_radio_button question.id.to_sym, key, label: { text: options["value"] }, hint: { text: options["hint"] }, - link_errors: index.zero? ? true : nil, + link_errors: index.zero? || nil, **stimulus_html_attributes(question) do %> <%= render partial: "#{conditional_question.type}_question", locals: { question: conditional_question, diff --git a/app/views/rails_admin/main/_submit_buttons.html.erb b/app/views/rails_admin/main/_submit_buttons.html.erb index 241624c4e..1768ce2b3 100644 --- a/app/views/rails_admin/main/_submit_buttons.html.erb +++ b/app/views/rails_admin/main/_submit_buttons.html.erb @@ -1,6 +1,6 @@
- +