diff --git a/Gemfile.lock b/Gemfile.lock index 9e0fe5371..2a9fb454f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -225,11 +225,11 @@ GEM net-protocol timeout nio4r (2.5.8) - nokogiri (1.13.8-arm64-darwin) + nokogiri (1.13.9-arm64-darwin) racc (~> 1.4) - nokogiri (1.13.8-x86_64-darwin) + nokogiri (1.13.9-x86_64-darwin) racc (~> 1.4) - nokogiri (1.13.8-x86_64-linux) + nokogiri (1.13.9-x86_64-linux) racc (~> 1.4) notifications-ruby-client (5.3.0) jwt (>= 1.5, < 3) diff --git a/app/components/search_component.html.erb b/app/components/search_component.html.erb index c63039b8c..2c10f3ed8 100644 --- a/app/components/search_component.html.erb +++ b/app/components/search_component.html.erb @@ -10,6 +10,6 @@ autocomplete: "off", class: "app-search__input" %> - <%= f.govuk_submit "Search", classes: "app-search__button" %> + <%= f.govuk_submit "Search", classes: "app-search__button govuk-button--secondary" %> <% end %> diff --git a/app/components/search_component.rb b/app/components/search_component.rb index 035500b54..e9fe83a3a 100644 --- a/app/components/search_component.rb +++ b/app/components/search_component.rb @@ -15,6 +15,10 @@ class SearchComponent < ViewComponent::Base request.path elsif request.path.include?("organisations") && request.path.include?("schemes") request.path + elsif request.path.include?("organisations") && request.path.include?("housing-providers") + request.path + elsif request.path.include?("organisations") && request.path.include?("managing-agents") + request.path elsif request.path.include?("users") user_path(current_user) elsif request.path.include?("organisations") diff --git a/app/controllers/organisation_relationships_controller.rb b/app/controllers/organisation_relationships_controller.rb new file mode 100644 index 000000000..f731209a8 --- /dev/null +++ b/app/controllers/organisation_relationships_controller.rb @@ -0,0 +1,125 @@ +class OrganisationRelationshipsController < ApplicationController + include Pagy::Backend + include Modules::SearchFilter + + before_action :authenticate_user! + before_action :authenticate_scope! + + def housing_providers + housing_providers = organisation.housing_providers + unpaginated_filtered_housing_providers = filtered_collection(housing_providers, search_term) + organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name) + respond_to do |format| + format.html do + @pagy, @housing_providers = pagy(unpaginated_filtered_housing_providers) + @organisations = organisations + @searched = search_term.presence + @total_count = housing_providers.size + render "organisation_relationships/housing_providers", layout: "application" + end + end + end + + def managing_agents + managing_agents = organisation.managing_agents + unpaginated_filtered_managing_agents = filtered_collection(managing_agents, search_term) + organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name) + respond_to do |format| + format.html do + @pagy, @managing_agents = pagy(unpaginated_filtered_managing_agents) + @organisations = organisations + @searched = search_term.presence + @total_count = managing_agents.size + render "organisation_relationships/managing_agents", layout: "application" + end + end + end + + def add_housing_provider + @organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name) + respond_to do |format| + format.html do + render "organisation_relationships/add_housing_provider", layout: "application" + end + end + end + + def add_managing_agent + @organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name) + respond_to do |format| + format.html do + render "organisation_relationships/add_managing_agent", layout: "application" + end + end + end + + def create_housing_provider + child_organisation_id = @organisation.id + parent_organisation_id = related_organisation_id + relationship_type = OrganisationRelationship::OWNING + if related_organisation_id.empty? + @organisation.errors.add :related_organisation_id, "You must choose a housing provider" + @organisations = Organisation.where.not(id: child_organisation_id).pluck(:id, :name) + render "organisation_relationships/add_housing_provider" + return + elsif OrganisationRelationship.exists?(child_organisation_id:, parent_organisation_id:, relationship_type:) + @organisation.errors.add :related_organisation_id, "You have already added this housing provider" + @organisations = Organisation.where.not(id: child_organisation_id).pluck(:id, :name) + render "organisation_relationships/add_housing_provider" + return + end + create!(child_organisation_id:, parent_organisation_id:, relationship_type:) + redirect_to housing_providers_organisation_path(related_organisation_id:) + end + + def create_managing_agent + parent_organisation_id = @organisation.id + child_organisation_id = related_organisation_id + relationship_type = OrganisationRelationship::MANAGING + + if related_organisation_id.empty? + @organisation.errors.add :related_organisation_id, "You must choose a managing agent" + @organisations = Organisation.where.not(id: parent_organisation_id).pluck(:id, :name) + render "organisation_relationships/add_managing_agent" + return + elsif OrganisationRelationship.exists?(child_organisation_id:, parent_organisation_id:, relationship_type:) + @organisation.errors.add :related_organisation_id, "You have already added this managing agent" + @organisations = Organisation.where.not(id: parent_organisation_id).pluck(:id, :name) + render "organisation_relationships/add_managing_agent" + return + end + + create!(child_organisation_id:, parent_organisation_id:, relationship_type:) + redirect_to managing_agents_organisation_path(related_organisation_id:) + end + +private + + def create!(child_organisation_id:, parent_organisation_id:, relationship_type:) + @resource = OrganisationRelationship.new(child_organisation_id:, parent_organisation_id:, relationship_type:) + @resource.save! + end + + def create(child_organisation_id, parent_organisation_id, relationship_type) + @resource = OrganisationRelationship.new(child_organisation_id:, parent_organisation_id:, relationship_type:) + @resource.save! + end + + def related_organisation_id + params["organisation"]["related_organisation_id"] + end + + def organisation + @organisation ||= Organisation.find(params[:id]) + end + + def search_term + params["search"] + end + + def authenticate_scope! + if current_user.organisation != organisation && !current_user.support? + render_not_found + end + end +end diff --git a/app/frontend/styles/_accessible-autocomplete.scss b/app/frontend/styles/_accessible-autocomplete.scss index 28e1b7e25..a59b38f44 100644 --- a/app/frontend/styles/_accessible-autocomplete.scss +++ b/app/frontend/styles/_accessible-autocomplete.scss @@ -5,12 +5,22 @@ .autocomplete__input { font-family: inherit; + background-image: url("data:image/svg+xml,%3Csvg class='app-search__icon' width='20' height='20' viewBox='0 0 27 27' fill='none' xmlns='http://www.w3.org/2000/svg' aria-hidden='true' focusable='false'%3E%3Ccircle cx='12.0161' cy='11.0161' r='8.51613' stroke='currentColor' stroke-width='3'%3E%3C/circle%3E%3Cline x1='17.8668' y1='17.3587' x2='26.4475' y2='25.9393' stroke='currentColor' stroke-width='3'%3E%3C/line%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-size: 1em 1em; + background-position: 7px center; + text-indent: govuk-spacing(6); } .autocomplete__option__append { font-weight: bold; } +.autocomplete__hint { + font-family: inherit; + text-indent: govuk-spacing(6); +} + .autocomplete__option__hint { display: block; color: $govuk-secondary-text-colour; diff --git a/app/helpers/navigation_items_helper.rb b/app/helpers/navigation_items_helper.rb index 3ac422c2d..e99ee4a26 100644 --- a/app/helpers/navigation_items_helper.rb +++ b/app/helpers/navigation_items_helper.rb @@ -17,6 +17,8 @@ module NavigationItemsHelper NavigationItem.new("Schemes", "/schemes", subnav_supported_housing_schemes_path?(path)), NavigationItem.new("Users", users_organisation_path(current_user.organisation), subnav_users_path?(path)), NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", subnav_details_path?(path)), + (NavigationItem.new("Housing providers", housing_providers_organisation_path(current_user.organisation), housing_providers_path?(path)) if FeatureToggle.managing_owning_enabled?), + (NavigationItem.new("Managing agents", managing_agents_organisation_path(current_user.organisation), managing_agents_path?(path)) if FeatureToggle.managing_owning_enabled?), ].compact else [ @@ -24,6 +26,8 @@ module NavigationItemsHelper FeatureToggle.sales_log_enabled? ? NavigationItem.new("Sales logs", sales_logs_path, sales_logs_current?(path)) : nil, NavigationItem.new("Users", users_organisation_path(current_user.organisation), subnav_users_path?(path)), NavigationItem.new("About your organisation", "/organisations/#{current_user.organisation.id}", subnav_details_path?(path)), + (NavigationItem.new("Housing providers", housing_providers_organisation_path(current_user.organisation), housing_providers_path?(path)) if FeatureToggle.managing_owning_enabled?), + (NavigationItem.new("Managing agents", managing_agents_organisation_path(current_user.organisation), managing_agents_path?(path)) if FeatureToggle.managing_owning_enabled?), ].compact end end @@ -31,18 +35,22 @@ module NavigationItemsHelper def secondary_items(path, current_organisation_id) if current_user.organisation.holds_own_stock? [ - NavigationItem.new("Lettings logs", "/organisations/#{current_organisation_id}/lettings-logs", subnav_logs_path?(path)), - FeatureToggle.sales_log_enabled? ? NavigationItem.new("Sales logs", "/organisations/#{current_organisation_id}/sales-logs", sales_logs_current?(path)) : nil, + NavigationItem.new("Lettings logs", "/organisations/#{current_organisation_id}/lettings-logs", subnav_lettings_logs_path?(path)), + FeatureToggle.sales_log_enabled? ? NavigationItem.new("Sales logs", "/organisations/#{current_organisation_id}/sales-logs", subnav_sales_logs_path?(path)) : nil, NavigationItem.new("Schemes", "/organisations/#{current_organisation_id}/schemes", subnav_supported_housing_schemes_path?(path)), NavigationItem.new("Users", "/organisations/#{current_organisation_id}/users", subnav_users_path?(path)), NavigationItem.new("About this organisation", "/organisations/#{current_organisation_id}", subnav_details_path?(path)), + (NavigationItem.new("Housing providers", housing_providers_organisation_path(current_user.organisation), housing_providers_path?(path)) if FeatureToggle.managing_owning_enabled?), + (NavigationItem.new("Managing agents", managing_agents_organisation_path(current_user.organisation), managing_agents_path?(path)) if FeatureToggle.managing_owning_enabled?), ].compact else [ - NavigationItem.new("Lettings logs", "/organisations/#{current_organisation_id}/lettings-logs", subnav_logs_path?(path)), + NavigationItem.new("Lettings logs", "/organisations/#{current_organisation_id}/lettings-logs", subnav_lettings_logs_path?(path)), FeatureToggle.sales_log_enabled? ? NavigationItem.new("Sales logs", "/organisations/#{current_organisation_id}/sales-logs", sales_logs_current?(path)) : nil, NavigationItem.new("Users", "/organisations/#{current_organisation_id}/users", subnav_users_path?(path)), NavigationItem.new("About this organisation", "/organisations/#{current_organisation_id}", subnav_details_path?(path)), + (NavigationItem.new("Housing providers", housing_providers_organisation_path(current_user.organisation), housing_providers_path?(path)) if FeatureToggle.managing_owning_enabled?), + (NavigationItem.new("Managing agents", managing_agents_organisation_path(current_user.organisation), managing_agents_path?(path)) if FeatureToggle.managing_owning_enabled?), ].compact end end @@ -84,11 +92,23 @@ private (path.include?("/organisations") && path.include?("/users")) || path.include?("/users/") end - def subnav_logs_path?(path) + def subnav_lettings_logs_path?(path) path.include?("/organisations") && path.include?("/lettings-logs") end + def subnav_sales_logs_path?(path) + path.include?("/organisations") && path.include?("/sales-logs") + end + def subnav_details_path?(path) path.include?("/organisations") && path.include?("/details") end + + def housing_providers_path?(path) + path.include?("/housing-providers") + end + + def managing_agents_path?(path) + path.include?("/managing-agents") + end end diff --git a/app/models/bulk_upload.rb b/app/models/bulk_upload.rb index 183dc274e..fa2a7a0e9 100644 --- a/app/models/bulk_upload.rb +++ b/app/models/bulk_upload.rb @@ -35,10 +35,7 @@ class BulkUpload created_by: current_user, ) map_row(row).each do |attr_key, attr_val| - update = lettings_log.update(attr_key => attr_val) - unless update - # TODO: determine what to do when a bulk upload contains field values that don't pass validations - end + _update = lettings_log.update(attr_key => attr_val) rescue ArgumentError # TODO: determine what we want to do when bulk upload contains totally invalid data for a field. end diff --git a/app/models/form/lettings/questions/scheme_id.rb b/app/models/form/lettings/questions/scheme_id.rb index 064be8032..7d7966c00 100644 --- a/app/models/form/lettings/questions/scheme_id.rb +++ b/app/models/form/lettings/questions/scheme_id.rb @@ -33,10 +33,6 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question !supported_housing_selected?(lettings_log) end - def answer_selected?(lettings_log, answer) - lettings_log[id] == answer.name || lettings_log[id] == answer.resource - end - private def supported_housing_selected?(lettings_log) diff --git a/app/models/form/sales/pages/buyer1_income.rb b/app/models/form/sales/pages/buyer1_income.rb new file mode 100644 index 000000000..e4f88be81 --- /dev/null +++ b/app/models/form/sales/pages/buyer1_income.rb @@ -0,0 +1,16 @@ +class Form::Sales::Pages::Buyer1Income < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "buyer_1_income" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Sales::Questions::Buyer1IncomeKnown.new(nil, nil, self), + Form::Sales::Questions::Buyer1Income.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/pages/property_local_authority.rb b/app/models/form/sales/pages/property_local_authority.rb new file mode 100644 index 000000000..1698ace47 --- /dev/null +++ b/app/models/form/sales/pages/property_local_authority.rb @@ -0,0 +1,16 @@ +class Form::Sales::Pages::PropertyLocalAuthority < ::Form::Page + def initialize(id, hsh, subsection) + super + @id = "property_local_authority" + @header = "" + @description = "" + @subsection = subsection + end + + def questions + @questions ||= [ + Form::Sales::Questions::PropertyLocalAuthorityKnown.new(nil, nil, self), + Form::Sales::Questions::PropertyLocalAuthority.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/questions/buyer1_income.rb b/app/models/form/sales/questions/buyer1_income.rb new file mode 100644 index 000000000..f4e586b39 --- /dev/null +++ b/app/models/form/sales/questions/buyer1_income.rb @@ -0,0 +1,14 @@ +class Form::Sales::Questions::Buyer1Income < ::Form::Question + def initialize(id, hsh, page) + super + @id = "income1" + @check_answer_label = "Buyer 1’s gross annual income" + @header = "Buyer 1’s gross annual income" + @type = "numeric" + @page = page + @min = 0 + @step = 1 + @width = 5 + @prefix = "£" + end +end diff --git a/app/models/form/sales/questions/buyer1_income_known.rb b/app/models/form/sales/questions/buyer1_income_known.rb new file mode 100644 index 000000000..923045ef9 --- /dev/null +++ b/app/models/form/sales/questions/buyer1_income_known.rb @@ -0,0 +1,21 @@ +class Form::Sales::Questions::Buyer1IncomeKnown < ::Form::Question + def initialize(id, hsh, page) + super + @id = "income1nk" + @check_answer_label = "Buyer 1’s gross annual income" + @header = "Do you know buyer 1’s annual income?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @page = page + @guidance_position = GuidancePosition::BOTTOM + @guidance_partial = "what_counts_as_income_sales" + @conditional_for = { + "income1" => [0], + } + end + + ANSWER_OPTIONS = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }.freeze +end diff --git a/app/models/form/sales/questions/property_local_authority.rb b/app/models/form/sales/questions/property_local_authority.rb new file mode 100644 index 000000000..462956eeb --- /dev/null +++ b/app/models/form/sales/questions/property_local_authority.rb @@ -0,0 +1,331 @@ +class Form::Sales::Questions::PropertyLocalAuthority < ::Form::Question + def initialize(id, hsh, page) + super + @id = "la" + @check_answer_label = "Local authority" + @header = "What is the local authority of the property?" + @type = "select" + @answer_options = ANSWER_OPTIONS + @page = page + end + + ANSWER_OPTIONS = { + "" => "Select an option", + "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 +end diff --git a/app/models/form/sales/questions/property_local_authority_known.rb b/app/models/form/sales/questions/property_local_authority_known.rb new file mode 100644 index 000000000..11ebeca6a --- /dev/null +++ b/app/models/form/sales/questions/property_local_authority_known.rb @@ -0,0 +1,24 @@ +class Form::Sales::Questions::PropertyLocalAuthorityKnown < ::Form::Question + def initialize(id, hsh, page) + super + @id = "la_known" + @check_answer_label = "Local authority known" + @header = "Do you know the local authority of the property?" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @conditional_for = { "la" => [1] } + @hidden_in_check_answers = { + "depends_on" => [ + { + "la_known" => 1, + }, + ], + } + @page = page + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "0" => { "value" => "No" }, + }.freeze +end diff --git a/app/models/form/sales/sections/finances.rb b/app/models/form/sales/sections/finances.rb new file mode 100644 index 000000000..c2c4082fd --- /dev/null +++ b/app/models/form/sales/sections/finances.rb @@ -0,0 +1,12 @@ +class Form::Sales::Sections::Finances < ::Form::Section + def initialize(id, hsh, form) + super + @id = "finances" + @label = "Finances" + @description = "" + @form = form + @subsections = [ + Form::Sales::Subsections::IncomeBenefitsAndOutgoings.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/subsections/income_benefits_and_outgoings.rb b/app/models/form/sales/subsections/income_benefits_and_outgoings.rb new file mode 100644 index 000000000..2c9d779b4 --- /dev/null +++ b/app/models/form/sales/subsections/income_benefits_and_outgoings.rb @@ -0,0 +1,15 @@ +class Form::Sales::Subsections::IncomeBenefitsAndOutgoings < ::Form::Subsection + def initialize(id, hsh, section) + super + @id = "income_benefits_and_outgoings" + @label = "Income, benefits and outgoings" + @section = section + @depends_on = [{ "setup" => "completed" }] + end + + def pages + @pages ||= [ + Form::Sales::Pages::Buyer1Income.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/subsections/property_information.rb b/app/models/form/sales/subsections/property_information.rb index 61791cb79..5ebe7b581 100644 --- a/app/models/form/sales/subsections/property_information.rb +++ b/app/models/form/sales/subsections/property_information.rb @@ -12,6 +12,7 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection Form::Sales::Pages::PropertyNumberOfBedrooms.new(nil, nil, self), Form::Sales::Pages::PropertyBuildingType.new(nil, nil, self), Form::Sales::Pages::PropertyUnitType.new(nil, nil, self), + Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self), ] end end diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb index c9d45e876..c6dde13ab 100644 --- a/app/models/form_handler.rb +++ b/app/models/form_handler.rb @@ -22,6 +22,7 @@ class FormHandler sales_sections = [ Form::Sales::Sections::PropertyInformation, Form::Sales::Sections::Household, + Form::Sales::Sections::Finances, ] current_form = Form.new(nil, current_collection_start_year, sales_sections, "sales") previous_form = Form.new(nil, current_collection_start_year - 1, sales_sections, "sales") diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 9eb039ab1..e420ca9d8 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -13,9 +13,13 @@ class Organisation < ApplicationRecord has_many :child_organisation_relationships, foreign_key: :parent_organisation_id, class_name: "OrganisationRelationship" has_many :child_organisations, through: :child_organisation_relationships + has_many :housing_provider_relationships, -> { where(relationship_type: OrganisationRelationship::OWNING) }, foreign_key: :child_organisation_id, class_name: "OrganisationRelationship" + has_many :housing_providers, through: :housing_provider_relationships, source: :parent_organisation + has_many :managing_agent_relationships, -> { where(relationship_type: OrganisationRelationship::MANAGING) }, foreign_key: :parent_organisation_id, class_name: "OrganisationRelationship" + has_many :managing_agents, through: :managing_agent_relationships, source: :child_organisation + scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } scope :search_by, ->(param) { search_by_name(param) } - has_paper_trail auto_strip_attributes :name @@ -82,9 +86,9 @@ class Organisation < ApplicationRecord { name: "Registration number", value: housing_registration_no || "", editable: false }, { name: "Rent_periods", value: rent_period_labels, editable: false, format: :bullet }, { name: "Owns housing stock", value: holds_own_stock ? "Yes" : "No", editable: false }, - { name: "Other stock owners", value: other_stock_owners, editable: false }, - { name: "Managing agents", value: managing_agents, editable: false }, + ({ name: "Other stock owners", value: other_stock_owners, editable: false } unless FeatureToggle.managing_owning_enabled?), + ({ name: "Managing agents", value: managing_agents_label, editable: false } unless FeatureToggle.managing_owning_enabled?), { name: "Data protection agreement", value: data_protection_agreement_string, editable: false }, - ] + ].compact end end diff --git a/app/models/organisation_relationship.rb b/app/models/organisation_relationship.rb index 034fc5d0e..acda8d2c4 100644 --- a/app/models/organisation_relationship.rb +++ b/app/models/organisation_relationship.rb @@ -1,4 +1,13 @@ class OrganisationRelationship < ApplicationRecord belongs_to :child_organisation, class_name: "Organisation" belongs_to :parent_organisation, class_name: "Organisation" + + OWNING = "owning".freeze + MANAGING = "managing".freeze + RELATIONSHIP_TYPE = { + OWNING => 0, + MANAGING => 1, + }.freeze + + enum relationship_type: RELATIONSHIP_TYPE end diff --git a/app/views/form/guidance/_what_counts_as_income_sales.html.erb b/app/views/form/guidance/_what_counts_as_income_sales.html.erb new file mode 100644 index 000000000..c5e2c7116 --- /dev/null +++ b/app/views/form/guidance/_what_counts_as_income_sales.html.erb @@ -0,0 +1,17 @@ +<%= govuk_details(summary_text: "What counts as income?") do %> +
You should include any income from:
+Don’t include:
+