diff --git a/app/controllers/organisation_relationships_controller.rb b/app/controllers/organisation_relationships_controller.rb index 355650914..d622fd17b 100644 --- a/app/controllers/organisation_relationships_controller.rb +++ b/app/controllers/organisation_relationships_controller.rb @@ -8,9 +8,11 @@ class OrganisationRelationshipsController < ApplicationController 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" @@ -31,18 +33,55 @@ class OrganisationRelationshipsController < ApplicationController 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 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!(child_organisation_id:, parent_organisation_id:, relationship_type:) + @resource = OrganisationRelationship.new(child_organisation_id:, parent_organisation_id:, relationship_type:) + @resource.save! + end + private def organisation @organisation ||= Organisation.find(params[:id]) end + def related_organisation_id + params["organisation"]["related_organisation_id"] + end + def search_term params["search"] end def authenticate_scope! - if current_user.organisation != organisation + if current_user.organisation != organisation && !current_user.support? render_not_found 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/views/logs/index.html.erb b/app/views/logs/index.html.erb index 4ccf4a3fb..431ca0f45 100644 --- a/app/views/logs/index.html.erb +++ b/app/views/logs/index.html.erb @@ -3,7 +3,11 @@ <% content_for :title, title %> -<%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Logs", sub: nil } : { main: "Logs", sub: current_user.organisation.name } %> +<% if current_page?(controller: 'lettings_logs', action: 'index') %> + <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Lettings logs", sub: nil } : { main: "Lettings logs", sub: current_user.organisation.name } %> +<% elsif current_page?(controller: 'sales_logs', action: 'index') %> + <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Sales logs", sub: nil } : { main: "Sales logs", sub: current_user.organisation.name } %> +<% end %>
diff --git a/app/views/organisation_relationships/_related_organisation_select_question.html.erb b/app/views/organisation_relationships/_related_organisation_select_question.html.erb new file mode 100644 index 000000000..cc27c2b8b --- /dev/null +++ b/app/views/organisation_relationships/_related_organisation_select_question.html.erb @@ -0,0 +1,3 @@ +<% answers = question.answer_options.map { |key, value| OpenStruct.new(id: key, name: value) } %> +<%= f.govuk_collection_select :related_organisation_id, answers, :id, :name, label: { hidden: true }, "data-controller": "accessible-autocomplete" do %> +<% end %> diff --git a/app/views/organisation_relationships/add_housing_provider.html.erb b/app/views/organisation_relationships/add_housing_provider.html.erb new file mode 100644 index 000000000..638d0e00f --- /dev/null +++ b/app/views/organisation_relationships/add_housing_provider.html.erb @@ -0,0 +1,36 @@ +<%= form_with model: @organisation, url: housing_providers_organisation_path, method: "post", local: true do |f| %> + <% if current_user.support? %> + <%= render partial: "organisations/headings", locals: { main: @organisation.name, sub: nil } %> + <%= render SubNavigationComponent.new(items: secondary_items(request.path, @organisation.id)) %> +

Add Housing Provider

+ <% end %> + <% if current_user.support? %> + <%= govuk_back_link(href: :back) %> + <%= render partial: "organisations/headings", locals: { main: "What is the name of this organisation's housing provider?", sub: nil } %> +

Start typing to search for a housing provider

+ <% else %> + <% content_for :before_content do %> + <%= govuk_back_link(href: :back) %> + <% end %> + <%= render partial: "organisations/headings", locals: { main: "What is the name of your housing provider?", sub: nil } %> +

Start typing to search for your housing provider

+ <% end %> + <% answer_options = { "" => "Select an option" } %> + <% @organisations.each do |organisation| %> + <% answer_options[organisation[0]] = organisation[1] %> + <% end %> + <%= render partial: "organisation_relationships/related_organisation_select_question", locals: { + question: Form::Question.new("", { "answer_options" => answer_options }, nil), + f:, + } %> + <%= f.govuk_submit "Add" %> + <%= govuk_details(summary_text: "Can't find the housing provider you're looking for?") do %> + + <% end %> +<% end %> diff --git a/app/views/organisation_relationships/housing_providers.html.erb b/app/views/organisation_relationships/housing_providers.html.erb index 9f839c58f..9ff96e68d 100644 --- a/app/views/organisation_relationships/housing_providers.html.erb +++ b/app/views/organisation_relationships/housing_providers.html.erb @@ -1,21 +1,45 @@ <% item_label = format_label(@pagy.count, "housing providers") %> -<% title = "Housing Providers" %> -<% content_for :title, title %> + +<% if current_user.data_coordinator? %> + <% if params["related_organisation_id"] %> + <%= govuk_notification_banner( + title_text: "Success", + success: true, title_heading_level: 3, + title_id: "swanky-notifications" + ) do |notification_banner| + notification_banner.heading(text: "#{Organisation.find(params['related_organisation_id']).name} is now one of your housing providers") + end %> + <% end %> +<% end %> <% if current_user.support? %> <%= render partial: "organisations/headings", locals: { main: @organisation.name, sub: nil } %> <%= render SubNavigationComponent.new(items: secondary_items(request.path, @organisation.id)) %>

Housing Providers

+ <% if params["related_organisation_id"] %> + <%= govuk_notification_banner( + title_text: "Success", + success: true, title_heading_level: 3, + title_id: "swanky-notifications" + ) do |notification_banner| + notification_banner.heading(text: "#{Organisation.find(params['related_organisation_id']).name} is now one of this organisation's housing providers") + end %> + <% end %>

This organisation can submit logs for its housing providers.

+ <% if @total_count == 0 %> +

This organisation does not currently have any housing providers.

+ <% end %> <% else %> - <%= render partial: "organisations/headings", locals: { main: "Your housing providers", sub: nil } %> + <%= render partial: "organisations/headings", locals: { main: "Your housing providers", sub: current_user.organisation.name } %>

Your organisation can submit logs for its housing providers.

+ <% if @total_count == 0 %> +

You do not currently have any housing providers.

+ <% end %> <% end %> -<% if @total_count == 0 %> -

This organisation does not currently have any housing providers.

-<% end %> -<% if current_user.data_coordinator? || current_user.support? %> - <%= govuk_button_link_to "Add a housing provider", housing_providers_organisation_path(organisation_id: @organisation.id), html: { method: :get } %> +<% if current_user.support? %> + <%= govuk_button_link_to "Add a housing provider", housing_providers_add_organisation_path(organisation_id: @organisation.id), html: { method: :get } %> + <% elsif current_user.data_coordinator? %> + <%= govuk_button_link_to "Add a housing provider", housing_providers_add_organisation_path, html: { method: :get } %> <% end %> <% if @total_count != 0 %> <%= render SearchComponent.new(current_user:, search_label: "Search for a housing provider", value: @searched) %> diff --git a/config/routes.rb b/config/routes.rb index 9474c5e3f..eae1b159c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,8 @@ Rails.application.routes.draw do get "logs/csv-confirmation", to: "lettings_logs#csv_confirmation" get "schemes", to: "organisations#schemes" get "housing-providers", to: "organisation_relationships#housing_providers" + get "housing-providers/add", to: "organisation_relationships#add_housing_provider" + post "housing-providers", to: "organisation_relationships#create_housing_provider" get "managing-agents", to: "organisation_relationships#managing_agents" end end diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 4268785c9..2557d6cb2 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -254,7 +254,7 @@ RSpec.describe OrganisationsController, type: :request do expect(response.body).to include(user.email) end - it "shows hidden accesibility fields only for active users in the current user's organisation" do + it "shows hidden accessibility fields only for active users in the current user's organisation" do expected_case_row_log = "User #{user.email}" unauthorized_case_row_log = "User #{other_org_user.email}" expect(CGI.unescape_html(response.body)).to include(expected_case_row_log) @@ -288,7 +288,7 @@ RSpec.describe OrganisationsController, type: :request do context "with an organisation that the user belongs to" do let!(:housing_provider) { FactoryBot.create(:organisation) } let!(:other_org_housing_provider) { FactoryBot.create(:organisation, name: "Foobar LTD") } - let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD") } + let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD 2") } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: housing_provider, relationship_type: OrganisationRelationship.relationship_types[:owning]) @@ -319,6 +319,20 @@ RSpec.describe OrganisationsController, type: :request do it "shows the pagination count" do expect(page).to have_content("1 total housing providers") end + + context "when adding a housing provider" do + before do + get "/organisations/#{organisation.id}/housing-providers/add", headers:, params: {} + end + + it "has the correct header" do + expect(response.body).to include("What is the name of your housing provider?") + end + + it "shows an add button" do + expect(page).to have_button("Add") + end + end end context "with an organisation that are not in scope for the user, i.e. that they do not belong to" do @@ -520,6 +534,34 @@ RSpec.describe OrganisationsController, type: :request do expect { request }.not_to change(Organisation, :count) end end + + describe "organisation_relationships#create_housing_provider" do + let!(:housing_provider) { FactoryBot.create(:organisation) } + + let(:params) do + { + "organisation": { + "related_organisation_id": housing_provider.id, + }, + } + end + + let(:request) { post "/organisations/#{organisation.id}/housing-providers", headers:, params: } + + it "creates a new organisation relationship" do + expect { request }.to change(OrganisationRelationship, :count).by(1) + end + + it "sets the organisation relationship attributes correctly" do + request + expect(OrganisationRelationship).to exist(child_organisation_id: organisation.id, parent_organisation_id: housing_provider.id, relationship_type: OrganisationRelationship::OWNING) + end + + it "redirects to the organisation list" do + request + expect(response).to redirect_to("/organisations/#{organisation.id}/housing-providers?related_organisation_id=#{housing_provider.id}") + end + end end context "with a data provider user" do @@ -1152,6 +1194,56 @@ RSpec.describe OrganisationsController, type: :request do end end + context "when viewing a specific organisation's housing providers" do + let!(:housing_provider) { FactoryBot.create(:organisation) } + let!(:other_org_housing_provider) { FactoryBot.create(:organisation, name: "Foobar LTD") } + let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD 2") } + + before do + FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: housing_provider, relationship_type: OrganisationRelationship.relationship_types[:owning]) + FactoryBot.create(:organisation_relationship, child_organisation: other_organisation, parent_organisation: other_org_housing_provider, relationship_type: OrganisationRelationship.relationship_types[:owning]) + get "/organisations/#{organisation.id}/housing-providers", headers:, params: {} + end + + it "displays the name of the organisation" do + expect(page).to have_content(organisation.name) + end + + it "has a sub-navigation with correct tabs" do + expect(page).to have_css(".app-sub-navigation") + expect(page).to have_content("Users") + end + + it "shows a table of housing providers" do + expected_html = "