From d54682b926cea6ad5ad39011dec535af41c91078 Mon Sep 17 00:00:00 2001 From: Kat Date: Tue, 3 Sep 2024 11:07:59 +0100 Subject: [PATCH] Add logs outcomes page --- app/helpers/merge_requests_helper.rb | 77 ++++++++++++ app/models/merge_request.rb | 10 +- .../merge_requests/logs_outcomes.html.erb | 27 +++++ spec/helpers/merge_requests_helper_spec.rb | 111 ++++++++++++++++++ .../merge_requests_controller_spec.rb | 29 +++++ 5 files changed, 249 insertions(+), 5 deletions(-) create mode 100644 app/views/merge_requests/logs_outcomes.html.erb diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index f5c78ac7b..0535eb012 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -196,4 +196,81 @@ module MergeRequestsHelper count = merge_request.total_visible_schemes_after_merge "#{"#{count} scheme".pluralize(count)} after merge" end + + def total_lettings_logs_after_merge_text(merge_request) + count = merge_request.total_visible_lettings_logs_after_merge + "#{"#{count} lettings log".pluralize(count)} after merge" + end + + def total_sales_logs_after_merge_text(merge_request) + count = merge_request.total_visible_sales_logs_after_merge + "#{"#{count} sales log".pluralize(count)} after merge" + end + + def merging_organisations_lettings_logs_outcomes_text(merge_request) + merging_organisations_logs_outcomes_text(merge_request, "lettings") + end + + def merging_organisations_sales_logs_outcomes_text(merge_request) + merging_organisations_logs_outcomes_text(merge_request, "sales") + end + + def merging_organisations_logs_outcomes_text(merge_request, type) + text = "" + if any_organisations_have_logs?(merge_request.merging_organisations, type) + text += "#{merge_request.absorbing_organisation.name} users will have access to all #{type} logs owned or managed by the merging organisations after the merge.

" + + if any_organisations_have_logs_after_merge_date?(merge_request.merging_organisations, type, merge_request.merge_date) + text += "#{type.capitalize} logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to #{merge_request.absorbing_organisation.name}.

" + end + + if any_organisations_share_logs?(merge_request.merging_organisations, type) + text += "Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.

" + end + end + + organisations_without_logs, organisations_with_logs = merge_request.merging_organisations.partition { |organisation| organisation.send("#{type}_logs").count.zero? } + if merge_request.absorbing_organisation.send("#{type}_logs").count.zero? + organisations_without_logs = [merge_request.absorbing_organisation] + organisations_without_logs + else + organisations_with_logs = [merge_request.absorbing_organisation] + organisations_with_logs + end + + if organisations_without_logs.any? + text += "#{organisations_without_logs.map(&:name).to_sentence} #{organisations_without_logs.count == 1 ? 'has' : 'have'} no #{type} logs.

" + end + + organisations_with_logs.each do |organisation| + text += "#{link_to_merging_organisation_logs(organisation, type)}

" + end + + text.html_safe + end + + def link_to_merging_organisation_logs(organisation, type) + count_text = organisation.send("#{type}_logs").count == 1 ? "1 #{organisation.name} #{type} log" : "all #{organisation.send("#{type}_logs").count} #{organisation.name} #{type} logs" + govuk_link_to "View #{count_text} (opens in a new tab)", send("#{type}_logs_organisation_path", organisation), target: "_blank" + end + + def lettings_logs_outcomes_header_text(merge_request) + count = merge_request.total_visible_lettings_logs_after_merge + "#{count} #{'lettings log'.pluralize(count)} after merge" + end + + def sales_logs_outcomes_header_text(merge_request) + count = merge_request.total_visible_sales_logs_after_merge + "#{count} #{'sales log'.pluralize(count)} after merge" + end + + def any_organisations_have_logs?(organisations, type) + organisations.any? { |organisation| organisation.send("#{type}_logs").count.positive? } + end + + def any_organisations_have_logs_after_merge_date?(organisations, type, merge_date) + organisations.any? { |organisation| organisation.send("#{type}_logs").after_date(merge_date).exists? } + end + + def any_organisations_share_logs?(organisations, type) + organisations.any? { |organisation| organisation.send("#{type}_logs").filter_by_managing_organisation(organisations.where.not(id: organisation.id)).exists? } + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 0a9e297cf..3a7f070d0 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -145,19 +145,19 @@ class MergeRequest < ApplicationRecord "#{stock_owners_count} #{'stock owner'.pluralize(stock_owners_count)}\n#{managing_agents_count} #{'managing agent'.pluralize(managing_agents_count)}" end - def total_sales_logs_after_merge + def total_visible_sales_logs_after_merge return total_sales_logs if status == STATUS[:request_merged] || status == STATUS[:processing] - (absorbing_organisation.sales_logs.pluck(:id) + merging_organisations.map { |org| org.sales_logs.pluck(:id) }.flatten).uniq.count + (absorbing_organisation.sales_logs.visible.pluck(:id) + merging_organisations.map { |org| org.sales_logs.visible.pluck(:id) }.flatten).uniq.count end - def total_lettings_logs_after_merge + def total_visible_lettings_logs_after_merge return total_lettings_logs if status == STATUS[:request_merged] || status == STATUS[:processing] - (absorbing_organisation.lettings_logs.pluck(:id) + merging_organisations.map { |org| org.lettings_logs.pluck(:id) }.flatten).uniq.count + (absorbing_organisation.lettings_logs.visible.pluck(:id) + merging_organisations.map { |org| org.lettings_logs.visible.pluck(:id) }.flatten).uniq.count end def total_logs_label - "#{total_lettings_logs_after_merge} lettings logs
#{total_sales_logs_after_merge} sales logs" + "#{total_visible_lettings_logs_after_merge} lettings logs
#{total_visible_sales_logs_after_merge} sales logs" end end diff --git a/app/views/merge_requests/logs_outcomes.html.erb b/app/views/merge_requests/logs_outcomes.html.erb new file mode 100644 index 000000000..9b16d451f --- /dev/null +++ b/app/views/merge_requests/logs_outcomes.html.erb @@ -0,0 +1,27 @@ +<% content_for :before_content do %> + <% title = "Users" %> + <% content_for :title, title %> + <%= govuk_back_link href: merge_request_path(@merge_request) %> +<% end %> + +

+ <%= @merge_request.absorbing_organisation_name %> + Logs +

+
+
+ <% unless @merge_request.status == "request_merged" || @merge_request.status == "processing" %> +

<%= total_lettings_logs_after_merge_text(@merge_request) %>

+

+ <%= merging_organisations_lettings_logs_outcomes_text(@merge_request) %> +

+ +
+ +

<%= total_sales_logs_after_merge_text(@merge_request) %>

+

+ <%= merging_organisations_sales_logs_outcomes_text(@merge_request) %> +

+ <% end %> +
+
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb index 8907ce70d..90bc9e79e 100644 --- a/spec/helpers/merge_requests_helper_spec.rb +++ b/spec/helpers/merge_requests_helper_spec.rb @@ -158,4 +158,115 @@ RSpec.describe MergeRequestsHelper do end end end + + describe "logs outcomes summary" do + let(:organisation) { create(:organisation, name: "Org 1") } + let(:merging_organisation) { create(:organisation, name: "Org 2") } + let(:merging_organisation_2) { create(:organisation, name: "Org 3") } + let(:merge_request) { create(:merge_request, absorbing_organisation: organisation, merge_date: Time.zone.today) } + + before do + create(:merge_request_organisation, merge_request:, merging_organisation:) + end + + context "when merging organisations don't have logs" do + it "returns the correct merging_organisations_lettings_logs_outcomes_text text" do + outcome_text = merging_organisations_lettings_logs_outcomes_text(merge_request) + expect(outcome_text).not_to include("Org 1 users will have access to all lettings logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).not_to include("Lettings logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).not_to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).to include("Org 1 and Org 2 have no lettings logs.") + end + + it "returns correct lettings_logs_outcomes_header_text" do + expect(lettings_logs_outcomes_header_text(merge_request)).to eq("0 lettings logs after merge") + end + + it "returns the correct merging_organisations_sales_logs_outcomes_text text" do + outcome_text = merging_organisations_sales_logs_outcomes_text(merge_request) + expect(outcome_text).not_to include("Org 1 users will have access to all sales logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).not_to include("Sales logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).not_to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).to include("Org 1 and Org 2 have no sales logs.") + end + + it "returns correct sales_logs_outcomes_header_text" do + expect(sales_logs_outcomes_header_text(merge_request)).to eq("0 sales logs after merge") + end + end + + context "when merging organisations have logs" do + before do + create(:lettings_log, owning_organisation: organisation) + create(:lettings_log, owning_organisation: merging_organisation, startdate: Time.zone.tomorrow) + create(:lettings_log, owning_organisation: merging_organisation, startdate: Time.zone.yesterday) + create(:sales_log, owning_organisation: organisation) + create(:sales_log, owning_organisation: merging_organisation, saledate: Time.zone.tomorrow) + create(:sales_log, owning_organisation: merging_organisation, saledate: Time.zone.yesterday) + end + + it "returns the correct merging_organisations_lettings_logs_outcomes_text text" do + outcome_text = merging_organisations_lettings_logs_outcomes_text(merge_request) + expect(outcome_text).to include("Org 1 users will have access to all lettings logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).to include("Lettings logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).not_to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).not_to include("Org 2 has no lettings logs.") + expect(outcome_text).to include("View all 2 Org 2 lettings logs (opens in a new tab)") + end + + it "returns correct lettings_logs_outcomes_header_text" do + expect(lettings_logs_outcomes_header_text(merge_request)).to eq("3 lettings logs after merge") + end + + it "returns the correct merging_organisations_sales_logs_outcomes_text text" do + outcome_text = merging_organisations_sales_logs_outcomes_text(merge_request) + expect(outcome_text).to include("Org 1 users will have access to all sales logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).to include("Sales logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).not_to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).not_to include("Org 2 has no sales logs.") + expect(outcome_text).to include("View all 2 Org 2 sales logs (opens in a new tab)") + end + + it "returns correct sales_logs_outcomes_header_text" do + expect(sales_logs_outcomes_header_text(merge_request)).to eq("3 sales logs after merge") + end + + context "when logs are owned and managed by organisations in the same merge" do + before do + create(:organisation_relationship, parent_organisation: merging_organisation_2, child_organisation: merging_organisation) + create(:merge_request_organisation, merge_request:, merging_organisation: merging_organisation_2) + create(:lettings_log, assigned_to: merging_organisation_2.users.first, owning_organisation: merging_organisation_2, managing_organisation: merging_organisation, startdate: Time.zone.yesterday) + create(:sales_log, assigned_to: merging_organisation_2.users.first, owning_organisation: merging_organisation_2, managing_organisation: merging_organisation, saledate: Time.zone.yesterday) + end + + it "returns the correct merging_organisations_lettings_logs_outcomes_text text" do + outcome_text = merging_organisations_lettings_logs_outcomes_text(merge_request) + expect(outcome_text).to include("Org 1 users will have access to all lettings logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).to include("Lettings logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).not_to include("Org 2 has no lettings logs.") + expect(outcome_text).to include("View all 3 Org 2 lettings logs (opens in a new tab)") + expect(outcome_text).to include("View 1 Org 3 lettings log (opens in a new tab)") + end + + it "returns correct lettings_logs_outcomes_header_text" do + expect(lettings_logs_outcomes_header_text(merge_request)).to eq("4 lettings logs after merge") + end + + it "returns the correct merging_organisations_sales_logs_outcomes_text text" do + outcome_text = merging_organisations_sales_logs_outcomes_text(merge_request) + expect(outcome_text).to include("Org 1 users will have access to all sales logs owned or managed by the merging organisations after the merge.") + expect(outcome_text).to include("Sales logs that are owned or managed by the merging organisations and have a tenancy start date after the merge date will have their owning or managing organisation changed to Org 1.") + expect(outcome_text).to include("Some logs are owned and managed by different organisations in this merge. They appear in the list for both the owning and the managing organisation.") + expect(outcome_text).not_to include("Org 2 has no sales logs.") + expect(outcome_text).to include("View all 3 Org 2 sales logs (opens in a new tab)") + expect(outcome_text).to include("View 1 Org 3 sales log (opens in a new tab)") + end + + it "returns correct sales_logs_outcomes_header_text" do + expect(sales_logs_outcomes_header_text(merge_request)).to eq("4 sales logs after merge") + end + end + end + end end diff --git a/spec/requests/merge_requests_controller_spec.rb b/spec/requests/merge_requests_controller_spec.rb index 2676563d7..74c784074 100644 --- a/spec/requests/merge_requests_controller_spec.rb +++ b/spec/requests/merge_requests_controller_spec.rb @@ -649,6 +649,35 @@ RSpec.describe MergeRequestsController, type: :request do expect(page).to have_content("13 schemes after merge") end end + + describe "#logs_outcomes" do + let(:merge_request) { create(:merge_request, absorbing_organisation: organisation) } + let(:organisation_with_no_logs) { create(:organisation, name: "Organisation with no logs") } + let(:organisation_with_no_logs_too) { create(:organisation, name: "Organisation with no logs too") } + let(:organisation_with_some_logs) { create(:organisation, name: "Organisation with some logs") } + + before do + create_list(:lettings_log, 4, owning_organisation: organisation_with_some_logs) + create_list(:sales_log, 2, owning_organisation: organisation_with_some_logs) + create_list(:lettings_log, 2, owning_organisation: organisation) + create_list(:sales_log, 3, owning_organisation: organisation) + create(:merge_request_organisation, merge_request:, merging_organisation: organisation_with_no_logs) + create(:merge_request_organisation, merge_request:, merging_organisation: organisation_with_no_logs_too) + create(:merge_request_organisation, merge_request:, merging_organisation: organisation_with_some_logs) + get "/merge-request/#{merge_request.id}/logs-outcomes", headers: + end + + it "shows logs outcomes after merge" do + expect(page).to have_link("View all 4 Organisation with some logs lettings logs (opens in a new tab)", href: lettings_logs_organisation_path(organisation_with_some_logs)) + expect(page).to have_link("View all 2 Organisation with some logs sales logs (opens in a new tab)", href: sales_logs_organisation_path(organisation_with_some_logs)) + expect(page).to have_link("View all 2 MHCLG lettings logs (opens in a new tab)", href: lettings_logs_organisation_path(organisation)) + expect(page).to have_link("View all 3 MHCLG sales logs (opens in a new tab)", href: sales_logs_organisation_path(organisation)) + expect(page).to have_content("Organisation with no logs and Organisation with no logs too have no lettings logs.") + expect(page).to have_content("Organisation with no logs and Organisation with no logs too have no sales logs.") + expect(page).to have_content("6 lettings logs after merge") + expect(page).to have_content("5 sales logs after merge") + end + end end context "when user is signed in with a data coordinator user" do