From d89e03cc621c2f73f7fde8c408dc4b798edaef90 Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Thu, 3 Nov 2022 10:11:25 +0000 Subject: [PATCH] Cldc 1675 rent validations (#959) * feat: add 2022 rent range data, update rake task for population of this * feat: change file format so ranges_rent_id is recognised * feat: add updated error messages and casing * tests: make tests pass * feat: ensure there is a location_code in all locations and use this (and beds = 0) for supported housing rent validations * feat: fix general needs validation behaviour * feat: add local authorities enum to location.rb * feat: ensure case when beds > 4 is accounted for * feat: add error messages on property postcode page as well as la page * feat: add error messages on scheme_id and location_id as well as la page * feat: add error messages on scheme_id and location_id as well as la page * feat: null coalescing and validations on changing las to one that invalidates rent in supported housing * feat: nil protection * refactor: linting * refactor: combining duplicated logic * tests: add hard validation tests split by needstype * feat: update validations when beds > 4 * feat: update validations when beds > 4 * refactor: simplification, use preivous la method * refactor: response to PR comments, fixing beds.negative validation * feat: remove dynamic local auth name text from interruption screens - to be added back in later if this becomes a priority, would need some work on adding local auth name to log for supported housing logs not just leaving it in the location --- app/controllers/locations_controller.rb | 43 +-- app/helpers/interruption_screen_helper.rb | 6 +- app/helpers/locations_helper.rb | 5 + app/models/la_rent_range.rb | 1 + app/models/lettings_log.rb | 10 +- app/models/location.rb | 321 ++++++++++++++++++ .../validations/financial_validations.rb | 11 +- .../validations/property_validations.rb | 4 +- app/models/validations/soft_validations.rb | 10 +- .../locations/edit_local_authority.html.erb | 6 +- config/forms/2021_2022.json | 10 - config/forms/2022_2023.json | 10 - config/locales/en.yml | 15 +- .../validations/financial_validations_spec.rb | 71 +++- .../validations/property_validations_spec.rb | 2 +- 15 files changed, 460 insertions(+), 65 deletions(-) diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 54e63d2cd..532ab915a 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -61,27 +61,32 @@ class LocationsController < ApplicationController error_message = I18n.t("validations.location_admin_district") @location.errors.add :location_admin_district, error_message render :edit_local_authority, status: :unprocessable_entity - elsif @location.update(location_params) - case page - when "edit" - if @location.location_admin_district.nil? - redirect_to(location_edit_local_authority_path(id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) - elsif location_params[:add_another_location] == "Yes" - redirect_to(new_location_path(@location.scheme)) - else - redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) - end - when "edit-name" - redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) - when "edit-local-authority" - if params[:add_another_location] == "Yes" - redirect_to(new_location_path(@location.scheme)) - else + else + if page == "edit-local-authority" + params[:location][:location_code] = Location.local_authorities.key(params[:location][:location_admin_district]) + end + if @location.update(location_params) + case page + when "edit" + if @location.location_admin_district.nil? + redirect_to(location_edit_local_authority_path(id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) + elsif location_params[:add_another_location] == "Yes" + redirect_to(new_location_path(@location.scheme)) + else + redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) + end + when "edit-name" redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) + when "edit-local-authority" + if params[:add_another_location] == "Yes" + redirect_to(new_location_path(@location.scheme)) + else + redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) + end end + else + render :edit, status: :unprocessable_entity end - else - render :edit, status: :unprocessable_entity end end @@ -123,7 +128,7 @@ private end def location_params - required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :add_another_location, :startdate, :mobility_type, :location_admin_district).merge(scheme_id: @scheme.id) + required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :add_another_location, :startdate, :mobility_type, :location_admin_district, :location_code).merge(scheme_id: @scheme.id) required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode] required_params end diff --git a/app/helpers/interruption_screen_helper.rb b/app/helpers/interruption_screen_helper.rb index 2dadeea89..7731d9425 100644 --- a/app/helpers/interruption_screen_helper.rb +++ b/app/helpers/interruption_screen_helper.rb @@ -6,11 +6,7 @@ module InterruptionScreenHelper informative_text["arguments"].each do |argument| value = if argument["label"] pre_casing_value = lettings_log.form.get_question(argument["key"], lettings_log).answer_label(lettings_log) - if argument["key"] == "la" - pre_casing_value - else - pre_casing_value.downcase - end + pre_casing_value.downcase else lettings_log.public_send(argument["key"]) end diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index 1d2412184..e0fe9d18c 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -12,6 +12,11 @@ module LocationsHelper selection_options(Location.type_of_units) end + def local_authorities_selection + null_option = [OpenStruct.new(id: "", name: "Select an option")] + null_option + Location.local_authorities.map { |code, name| OpenStruct.new(code:, name:) } + end + def selection_options(resource) return [] if resource.blank? diff --git a/app/models/la_rent_range.rb b/app/models/la_rent_range.rb index ad1d20b57..7a04f3356 100644 --- a/app/models/la_rent_range.rb +++ b/app/models/la_rent_range.rb @@ -1,2 +1,3 @@ class LaRentRange < ApplicationRecord + MAX_BEDS = 4 end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 9e38138eb..f09fd1ebd 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -435,13 +435,19 @@ class LettingsLog < Log Csv::LettingsLogCsvService.new(user).to_csv end + def beds_for_la_rent_range + return 0 if is_supported_housing? + + beds.nil? ? nil : [beds, LaRentRange::MAX_BEDS].min + end + def soft_min_for_period - soft_min = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype:).soft_min + soft_min = LaRentRange.find_by(start_year: collection_start_year, la:, beds: beds_for_la_rent_range, lettype:).soft_min "#{soft_value_for_period(soft_min)} #{SUFFIX_FROM_PERIOD[period].presence || 'every week'}" end def soft_max_for_period - soft_max = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype:).soft_max + soft_max = LaRentRange.find_by(start_year: collection_start_year, la:, beds: beds_for_la_rent_range, lettype:).soft_max "#{soft_value_for_period(soft_max)} #{SUFFIX_FROM_PERIOD[period].presence || 'every week'}" end diff --git a/app/models/location.rb b/app/models/location.rb index c89ff0236..40a115d43 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -17,6 +17,327 @@ class Location < ApplicationRecord scope :started, -> { where("startdate <= ?", Time.zone.today).or(where(startdate: nil)) } scope :active, -> { where(confirmed: true).and(started) } + LOCAL_AUTHORITIES = { + "E07000223": "Adur", + "E07000026": "Allerdale", + "E07000032": "Amber Valley", + "E07000224": "Arun", + "E07000170": "Ashfield", + "E07000105": "Ashford", + "E07000200": "Babergh", + "E09000002": "Barking and Dagenham", + "E09000003": "Barnet", + "E08000016": "Barnsley", + "E07000027": "Barrow-in-Furness", + "E07000066": "Basildon", + "E07000084": "Basingstoke and Deane", + "E07000171": "Bassetlaw", + "E06000022": "Bath and North East Somerset", + "E06000055": "Bedford", + "E09000004": "Bexley", + "E08000025": "Birmingham", + "E07000129": "Blaby", + "E06000008": "Blackburn with Darwen", + "E06000009": "Blackpool", + "E07000033": "Bolsover", + "E08000001": "Bolton", + "E07000136": "Boston", + "E06000058": "Bournemouth, Christchurch and Poole", + "E06000036": "Bracknell Forest", + "E08000032": "Bradford", + "E07000067": "Braintree", + "E07000143": "Breckland", + "E09000005": "Brent", + "E07000068": "Brentwood", + "E06000043": "Brighton and Hove", + "E06000023": "Bristol, City of", + "E07000144": "Broadland", + "E09000006": "Bromley", + "E07000234": "Bromsgrove", + "E07000095": "Broxbourne", + "E07000172": "Broxtowe", + "E06000060": "Buckinghamshire", + "E07000117": "Burnley", + "E08000002": "Bury", + "E08000033": "Calderdale", + "E07000008": "Cambridge", + "E09000007": "Camden", + "E07000192": "Cannock Chase", + "E07000106": "Canterbury", + "E07000028": "Carlisle", + "E07000069": "Castle Point", + "E06000056": "Central Bedfordshire", + "E07000130": "Charnwood", + "E07000070": "Chelmsford", + "E07000078": "Cheltenham", + "E07000177": "Cherwell", + "E06000049": "Cheshire East", + "E06000050": "Cheshire West and Chester", + "E07000034": "Chesterfield", + "E07000225": "Chichester", + "E07000118": "Chorley", + "E09000001": "City of London", + "E07000071": "Colchester", + "E07000029": "Copeland", + "E07000150": "Corby", + "E06000052": "Cornwall", + "E07000079": "Cotswold", + "E06000047": "County Durham", + "E08000026": "Coventry", + "E07000163": "Craven", + "E07000226": "Crawley", + "E09000008": "Croydon", + "E07000096": "Dacorum", + "E06000005": "Darlington", + "E07000107": "Dartford", + "E07000151": "Daventry", + "E06000015": "Derby", + "E07000035": "Derbyshire Dales", + "E08000017": "Doncaster", + "E06000059": "Dorset", + "E07000108": "Dover", + "E08000027": "Dudley", + "E09000009": "Ealing", + "E07000009": "East Cambridgeshire", + "E07000040": "East Devon", + "E07000085": "East Hampshire", + "E07000242": "East Hertfordshire", + "E07000137": "East Lindsey", + "E07000152": "East Northamptonshire", + "E06000011": "East Riding of Yorkshire", + "E07000193": "East Staffordshire", + "E07000244": "East Suffolk", + "E07000061": "Eastbourne", + "E07000086": "Eastleigh", + "E07000030": "Eden", + "E07000207": "Elmbridge", + "E09000010": "Enfield", + "E07000072": "Epping Forest", + "E07000208": "Epsom and Ewell", + "E07000036": "Erewash", + "E07000041": "Exeter", + "E07000087": "Fareham", + "E07000010": "Fenland", + "E07000112": "Folkestone and Hythe", + "E07000080": "Forest of Dean", + "E07000119": "Fylde", + "E08000037": "Gateshead", + "E07000173": "Gedling", + "E07000081": "Gloucester", + "E07000088": "Gosport", + "E07000109": "Gravesham", + "E07000145": "Great Yarmouth", + "E09000011": "Greenwich", + "E07000209": "Guildford", + "W06000002": "Gwynedd", + "E09000012": "Hackney", + "E06000006": "Halton", + "E07000164": "Hambleton", + "E09000013": "Hammersmith and Fulham", + "E07000131": "Harborough", + "E09000014": "Haringey", + "E07000073": "Harlow", + "E07000165": "Harrogate", + "E09000015": "Harrow", + "E07000089": "Hart", + "E06000001": "Hartlepool", + "E07000062": "Hastings", + "E07000090": "Havant", + "E09000016": "Havering", + "E06000019": "Herefordshire, County of", + "E07000098": "Hertsmere", + "E07000037": "High Peak", + "S12000017": "Highland", + "E09000017": "Hillingdon", + "E07000132": "Hinckley and Bosworth", + "E07000227": "Horsham", + "E09000018": "Hounslow", + "E07000011": "Huntingdonshire", + "E07000120": "Hyndburn", + "E07000202": "Ipswich", + "E06000046": "Isle of Wight", + "E06000053": "Isles of Scilly", + "E09000019": "Islington", + "E09000020": "Kensington and Chelsea", + "E07000153": "Kettering", + "E07000146": "King’s Lynn and West Norfolk", + "E06000010": "Kingston upon Hull, City of", + "E09000021": "Kingston upon Thames", + "E08000034": "Kirklees", + "E08000011": "Knowsley", + "E09000022": "Lambeth", + "E07000121": "Lancaster", + "E08000035": "Leeds", + "E06000016": "Leicester", + "E07000063": "Lewes", + "E09000023": "Lewisham", + "E07000194": "Lichfield", + "E07000138": "Lincoln", + "E08000012": "Liverpool", + "E06000032": "Luton", + "E07000110": "Maidstone", + "E07000074": "Maldon", + "E07000235": "Malvern Hills", + "E08000003": "Manchester", + "E07000174": "Mansfield", + "E06000035": "Medway", + "E07000133": "Melton", + "E07000187": "Mendip", + "E09000024": "Merton", + "E07000042": "Mid Devon", + "E07000203": "Mid Suffolk", + "E07000228": "Mid Sussex", + "E06000002": "Middlesbrough", + "E06000042": "Milton Keynes", + "E07000210": "Mole Valley", + "E07000091": "New Forest", + "E07000175": "Newark and Sherwood", + "E08000021": "Newcastle upon Tyne", + "E07000195": "Newcastle-under-Lyme", + "E09000025": "Newham", + "E07000043": "North Devon", + "E07000038": "North East Derbyshire", + "E06000012": "North East Lincolnshire", + "E07000099": "North Hertfordshire", + "E07000139": "North Kesteven", + "E06000013": "North Lincolnshire", + "E07000147": "North Norfolk", + "E06000024": "North Somerset", + "E08000022": "North Tyneside", + "E07000218": "North Warwickshire", + "E07000134": "North West Leicestershire", + "E07000154": "Northampton", + "E06000057": "Northumberland", + "E07000148": "Norwich", + "E06000018": "Nottingham", + "E07000219": "Nuneaton and Bedworth", + "E07000135": "Oadby and Wigston", + "E08000004": "Oldham", + "E07000178": "Oxford", + "E07000122": "Pendle", + "E06000031": "Peterborough", + "E06000026": "Plymouth", + "E06000044": "Portsmouth", + "E07000123": "Preston", + "E06000038": "Reading", + "E09000026": "Redbridge", + "E06000003": "Redcar and Cleveland", + "E07000236": "Redditch", + "E07000211": "Reigate and Banstead", + "E07000124": "Ribble Valley", + "E09000027": "Richmond upon Thames", + "E07000166": "Richmondshire", + "E08000005": "Rochdale", + "E07000075": "Rochford", + "E07000125": "Rossendale", + "E07000064": "Rother", + "E08000018": "Rotherham", + "E07000220": "Rugby", + "E07000212": "Runnymede", + "E07000176": "Rushcliffe", + "E07000092": "Rushmoor", + "E06000017": "Rutland", + "E07000167": "Ryedale", + "E08000006": "Salford", + "E08000028": "Sandwell", + "E07000168": "Scarborough", + "E07000188": "Sedgemoor", + "E08000014": "Sefton", + "E07000169": "Selby", + "E07000111": "Sevenoaks", + "E08000019": "Sheffield", + "E06000051": "Shropshire", + "E06000039": "Slough", + "E08000029": "Solihull", + "E07000246": "Somerset West and Taunton", + "E07000012": "South Cambridgeshire", + "E07000039": "South Derbyshire", + "E06000025": "South Gloucestershire", + "E07000044": "South Hams", + "E07000140": "South Holland", + "E07000141": "South Kesteven", + "E07000031": "South Lakeland", + "E07000149": "South Norfolk", + "E07000155": "South Northamptonshire", + "E07000179": "South Oxfordshire", + "E07000126": "South Ribble", + "E07000189": "South Somerset", + "E07000196": "South Staffordshire", + "E08000023": "South Tyneside", + "E06000045": "Southampton", + "E06000033": "Southend-on-Sea", + "E09000028": "Southwark", + "E07000213": "Spelthorne", + "E07000240": "St Albans", + "E08000013": "St. Helens", + "E07000197": "Stafford", + "E07000198": "Staffordshire Moorlands", + "E07000243": "Stevenage", + "E08000007": "Stockport", + "E06000004": "Stockton-on-Tees", + "E06000021": "Stoke-on-Trent", + "E07000221": "Stratford-on-Avon", + "E07000082": "Stroud", + "E08000024": "Sunderland", + "E07000214": "Surrey Heath", + "E09000029": "Sutton", + "E07000113": "Swale", + "E06000030": "Swindon", + "E08000008": "Tameside", + "E07000199": "Tamworth", + "E07000215": "Tandridge", + "E07000045": "Teignbridge", + "E06000020": "Telford and Wrekin", + "E07000076": "Tendring", + "E07000093": "Test Valley", + "E07000083": "Tewkesbury", + "E07000114": "Thanet", + "E07000102": "Three Rivers", + "E06000034": "Thurrock", + "E07000115": "Tonbridge and Malling", + "E06000027": "Torbay", + "E07000046": "Torridge", + "E09000030": "Tower Hamlets", + "E08000009": "Trafford", + "E07000116": "Tunbridge Wells", + "E07000077": "Uttlesford", + "E07000180": "Vale of White Horse", + "E08000036": "Wakefield", + "E08000030": "Walsall", + "E09000031": "Waltham Forest", + "E09000032": "Wandsworth", + "E06000007": "Warrington", + "E07000222": "Warwick", + "E07000103": "Watford", + "E07000216": "Waverley", + "E07000065": "Wealden", + "E07000156": "Wellingborough", + "E07000241": "Welwyn Hatfield", + "E06000037": "West Berkshire", + "E07000047": "West Devon", + "E07000127": "West Lancashire", + "E07000142": "West Lindsey", + "E07000181": "West Oxfordshire", + "E07000245": "West Suffolk", + "E09000033": "Westminster", + "E08000010": "Wigan", + "E06000054": "Wiltshire", + "E07000094": "Winchester", + "E06000040": "Windsor and Maidenhead", + "E08000015": "Wirral", + "E07000217": "Woking", + "E06000041": "Wokingham", + "E08000031": "Wolverhampton", + "E07000237": "Worcester", + "E07000229": "Worthing", + "E07000238": "Wychavon", + "E07000128": "Wyre", + "E07000239": "Wyre Forest", + "E06000014": "York", + }.freeze + + enum local_authorities: LOCAL_AUTHORITIES + MOBILITY_TYPE = { "Wheelchair-user standard": "W", "Fitted with equipment and adaptations": "A", diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index de7c4ab68..4dec7bb78 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -181,20 +181,27 @@ private return if record.startdate.blank? collection_year = record.collection_start_year - rent_range = LaRentRange.find_by(start_year: collection_year, la: record.la, beds: record.beds, lettype: record.lettype) + + rent_range = LaRentRange.find_by(start_year: collection_year, la: record.la, beds: record.beds_for_la_rent_range, lettype: record.lettype) if rent_range.present? && !weekly_value_in_range(record, "brent", rent_range.hard_min, rent_range.hard_max) && record.brent.present? && record.period.present? if record.weekly_value(record["brent"]) < rent_range.hard_min record.errors.add :brent, I18n.t("validations.financial.brent.below_hard_min") record.errors.add :beds, I18n.t("validations.financial.brent.beds.below_hard_min") record.errors.add :la, I18n.t("validations.financial.brent.la.below_hard_min") + record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.below_hard_min") + record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.below_hard_min") + record.errors.add :location_id, I18n.t("validations.financial.brent.location_id.below_hard_min") record.errors.add :rent_type, I18n.t("validations.financial.brent.rent_type.below_hard_min") record.errors.add :needstype, I18n.t("validations.financial.brent.needstype.below_hard_min") record.errors.add :period, I18n.t("validations.financial.brent.period.below_hard_min") - else + elsif record.beds.blank? || record.beds < LaRentRange::MAX_BEDS record.errors.add :brent, I18n.t("validations.financial.brent.above_hard_max") record.errors.add :beds, I18n.t("validations.financial.brent.beds.above_hard_max") record.errors.add :la, I18n.t("validations.financial.brent.la.above_hard_max") + record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.above_hard_max") + record.errors.add :scheme_id, I18n.t("validations.financial.brent.scheme_id.above_hard_max") + record.errors.add :location_id, I18n.t("validations.financial.brent.location_id.above_hard_max") record.errors.add :rent_type, I18n.t("validations.financial.brent.rent_type.above_hard_max") record.errors.add :needstype, I18n.t("validations.financial.brent.needstype.above_hard_max") record.errors.add :period, I18n.t("validations.financial.brent.period.above_hard_max") diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index dc14fc8fd..d5ab8e9e0 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -55,8 +55,8 @@ module Validations::PropertyValidations end def validate_shared_housing_rooms(record) - if record.beds.present? && record.beds.negative? - record.errors.add :beds, I18n.t("validations.property.beds.negative") + if record.beds.present? && record.beds <= 0 + record.errors.add :beds, I18n.t("validations.property.beds.non_positive") end unless record.unittype_gn.nil? diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index dd3e94b2e..944fff022 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -28,15 +28,19 @@ module Validations::SoftValidations def rent_in_soft_min_range? return unless brent && weekly_value(brent) && startdate - rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype: get_lettype) + rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds: beds_for_la_rent_range, lettype: get_lettype) rent_range.present? && weekly_value(brent).between?(rent_range.hard_min, rent_range.soft_min) end def rent_in_soft_max_range? return unless brent && weekly_value(brent) && startdate - rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds:, lettype: get_lettype) - rent_range.present? && weekly_value(brent).between?(rent_range.soft_max, rent_range.hard_max) + rent_range = LaRentRange.find_by(start_year: collection_start_year, la:, beds: beds_for_la_rent_range, lettype: get_lettype) + if beds.present? && rent_range.present? && beds > LaRentRange::MAX_BEDS + weekly_value(brent) > rent_range.soft_max + elsif rent_range.present? + weekly_value(brent).between?(rent_range.soft_max, rent_range.hard_max) + end end (1..8).each do |person_num| diff --git a/app/views/locations/edit_local_authority.html.erb b/app/views/locations/edit_local_authority.html.erb index 41cf74f1b..43c351d28 100644 --- a/app/views/locations/edit_local_authority.html.erb +++ b/app/views/locations/edit_local_authority.html.erb @@ -12,12 +12,8 @@ <%= render partial: "organisations/headings", locals: { main: "What is the local authority of #{@location.postcode}?", sub: @scheme.service_name } %> - <% la_list = FormHandler.instance.current_lettings_form.get_question("la", nil).answer_options.values %> - - <% las = la_list.map { |la| OpenStruct.new(name: la) } %> - <%= f.govuk_collection_select :location_admin_district, - las, + local_authorities_selection, :name, :name, label: { hidden: true }, diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index ec1875514..a180bcc67 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -8430,11 +8430,6 @@ "informative_text": { "translation": "soft_validations.rent.min.hint_text", "arguments": [ - { - "key": "la", - "label": true, - "i18n_template": "la" - }, { "key": "soft_min_for_period", "label": false, @@ -8487,11 +8482,6 @@ "informative_text": { "translation": "soft_validations.rent.max.hint_text", "arguments": [ - { - "key": "la", - "label": true, - "i18n_template": "la" - }, { "key": "soft_max_for_period", "label": false, diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index c7562a764..76595bdc5 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -8386,11 +8386,6 @@ "informative_text": { "translation": "soft_validations.rent.min.hint_text", "arguments": [ - { - "key": "la", - "label": true, - "i18n_template": "la" - }, { "key": "soft_min_for_period", "label": false, @@ -8443,11 +8438,6 @@ "informative_text": { "translation": "soft_validations.rent.max.hint_text", "arguments": [ - { - "key": "la", - "label": true, - "i18n_template": "la" - }, { "key": "soft_max_for_period", "label": false, diff --git a/config/locales/en.yml b/config/locales/en.yml index 853fabcb2..003f573dc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -146,7 +146,7 @@ en: one_seven_bedroom_shared: "A shared house must have 1 to 7 bedrooms" one_three_bedroom_single_tenant_shared: "A shared house with fewer than two tenants must have 1 to 3 bedrooms" beds: - negative: "Number of bedrooms has to be greater than 0" + non_positive: "Number of bedrooms has to be greater than 0" over_max: "Number of bedrooms cannot be more than 12" financial: @@ -190,6 +190,15 @@ en: brent: below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" + scheme_id: + below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period and local authority" + above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period and local authority" + location_id: + below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period and local authority" + above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period and local authority" + postcode_known: + below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period, local authority and number of bedrooms" + above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and number of bedrooms" la: below_hard_min: "Rent is below the absolute minimum expected for a property of this type based on this local authority" above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this local authority" @@ -313,10 +322,10 @@ en: rent: min: title_text: "You told us the rent is %{brent}" - hint_text: "The minimum rent expected for this type of property in %{la} is £%{soft_min_for_period}." + hint_text: "The minimum rent expected for this type of property in this local authority is £%{soft_min_for_period}." max: title_text: "You told us the rent is %{brent}" - hint_text: "The maximum rent expected for this type of property in %{la} is £%{soft_max_for_period}." + hint_text: "The maximum rent expected for this type of property in this local authority is £%{soft_max_for_period}." retirement: min: title: "You told us this person is under %{age} and retired" diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index 51811772d..c4c4958db 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -247,6 +247,8 @@ RSpec.describe Validations::FinancialValidations do end describe "rent and charges validations" do + let!(:location) { FactoryBot.create(:location, location_code: "E07000223") } + context "when the owning organisation is a private registered provider" do before { record.owning_organisation.provider_type = 2 } @@ -777,7 +779,7 @@ RSpec.describe Validations::FinancialValidations do context "when validating ranges based on LA and needstype" do before do - LaRentRange.create( + LaRentRange.create!( ranges_rent_id: "1", la: "E07000223", beds: 1, @@ -788,9 +790,21 @@ RSpec.describe Validations::FinancialValidations do hard_max: 100.99, start_year: 2021, ) + LaRentRange.create!( + ranges_rent_id: "2", + la: "E07000223", + beds: 0, + lettype: 2, + soft_min: 12.41, + soft_max: 89.54, + hard_min: 9.87, + hard_max: 100.99, + start_year: 2021, + ) end - it "validates hard minimum" do + it "validates hard minimum for general needs" do + record.needstype = 1 record.lettype = 1 record.period = 1 record.la = "E07000223" @@ -803,7 +817,21 @@ RSpec.describe Validations::FinancialValidations do .to include(match I18n.t("validations.financial.brent.below_hard_min")) end - it "validates hard max" do + it "validates hard minimum for supported housing" do + record.needstype = 2 + record.lettype = 2 + record.period = 1 + record.location = location + record.startdate = Time.zone.local(2021, 9, 17) + record.brent = 9.17 + + financial_validator.validate_rent_amount(record) + expect(record.errors["brent"]) + .to include(match I18n.t("validations.financial.brent.below_hard_min")) + end + + it "validates hard max for general needs" do + record.needstype = 1 record.lettype = 1 record.period = 1 record.la = "E07000223" @@ -818,10 +846,47 @@ RSpec.describe Validations::FinancialValidations do .to include(match I18n.t("validations.financial.brent.beds.above_hard_max")) expect(record.errors["la"]) .to include(match I18n.t("validations.financial.brent.la.above_hard_max")) + expect(record.errors["postcode_known"]) + .to include(match I18n.t("validations.financial.brent.postcode_known.above_hard_max")) + expect(record.errors["scheme_id"]) + .to include(match I18n.t("validations.financial.brent.scheme_id.above_hard_max")) + expect(record.errors["location_id"]) + .to include(match I18n.t("validations.financial.brent.location_id.above_hard_max")) + expect(record.errors["rent_type"]) + .to include(match I18n.t("validations.financial.brent.rent_type.above_hard_max")) + expect(record.errors["needstype"]) + .to include(match I18n.t("validations.financial.brent.needstype.above_hard_max")) + expect(record.errors["period"]) + .to include(match I18n.t("validations.financial.brent.period.above_hard_max")) + end + + it "validates hard max for supported housing" do + record.needstype = 2 + record.lettype = 2 + record.period = 1 + record.location = location + record.startdate = Time.zone.local(2021, 9, 17) + record.brent = 200 + + financial_validator.validate_rent_amount(record) + expect(record.errors["brent"]) + .to include(match I18n.t("validations.financial.brent.above_hard_max")) + expect(record.errors["beds"]) + .to include(match I18n.t("validations.financial.brent.beds.above_hard_max")) + expect(record.errors["la"]) + .to include(match I18n.t("validations.financial.brent.la.above_hard_max")) + expect(record.errors["postcode_known"]) + .to include(match I18n.t("validations.financial.brent.postcode_known.above_hard_max")) + expect(record.errors["scheme_id"]) + .to include(match I18n.t("validations.financial.brent.scheme_id.above_hard_max")) + expect(record.errors["location_id"]) + .to include(match I18n.t("validations.financial.brent.location_id.above_hard_max")) expect(record.errors["rent_type"]) .to include(match I18n.t("validations.financial.brent.rent_type.above_hard_max")) expect(record.errors["needstype"]) .to include(match I18n.t("validations.financial.brent.needstype.above_hard_max")) + expect(record.errors["period"]) + .to include(match I18n.t("validations.financial.brent.period.above_hard_max")) end it "validates hard max for correct collection year" do diff --git a/spec/models/validations/property_validations_spec.rb b/spec/models/validations/property_validations_spec.rb index 86f2b256e..153934ebc 100644 --- a/spec/models/validations/property_validations_spec.rb +++ b/spec/models/validations/property_validations_spec.rb @@ -134,7 +134,7 @@ RSpec.describe Validations::PropertyValidations do it "adds an error" do record.beds = -4 property_validator.validate_shared_housing_rooms(record) - expect(record.errors["beds"]).to include(I18n.t("validations.property.beds.negative")) + expect(record.errors["beds"]).to include(I18n.t("validations.property.beds.non_positive")) end end