From a68e7d5c3f301b6779cecc79d2bd158c3737ac1d Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 24 Jul 2023 12:12:56 +0100 Subject: [PATCH] Create merge_organisations_service --- .../merge/merge_organisations_service.rb | 73 ++++++++++++++++ .../merge/merge_organisations_service_spec.rb | 84 +++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 app/services/merge/merge_organisations_service.rb create mode 100644 spec/services/merge/merge_organisations_service_spec.rb diff --git a/app/services/merge/merge_organisations_service.rb b/app/services/merge/merge_organisations_service.rb new file mode 100644 index 000000000..77c81ec8a --- /dev/null +++ b/app/services/merge/merge_organisations_service.rb @@ -0,0 +1,73 @@ +class Merge::MergeOrganisationsService + def initialize(absorbing_organisation_id:, merging_organisation_ids:) + @absorbing_organisation = Organisation.find(absorbing_organisation_id) + @merging_organisations = Organisation.find(merging_organisation_ids) + end + + def call + merge_organisation_details + merge_rent_periods + merge_organisation_relationships + merge_users + mark_organisations_as_merged + @absorbing_organisation.save! + end + +private + + def merge_organisation_details + @absorbing_organisation.holds_own_stock = merge_boolean_organisation_attribute("holds_own_stock") + @absorbing_organisation.choice_based_lettings = merge_boolean_organisation_attribute("choice_based_lettings") + @absorbing_organisation.common_housing_register = merge_boolean_organisation_attribute("common_housing_register") + @absorbing_organisation.choice_allocation_policy = merge_boolean_organisation_attribute("choice_allocation_policy") + end + + def merge_rent_periods + @merging_organisations.each do |merging_organisation| + merging_organisation.rent_periods.each do |rent_period| + @absorbing_organisation.organisation_rent_periods << OrganisationRentPeriod.new(rent_period:) unless @absorbing_organisation.rent_periods.include?(rent_period) + end + end + end + + def merge_organisation_relationships + @merging_organisations.each do |merging_organisation| + merging_organisation.parent_organisation_relationships.each do |parent_organisation_relationship| + if parent_relationship_exists_on_absorbing_organisation?(parent_organisation_relationship) + parent_organisation_relationship.destroy! + else + parent_organisation_relationship.update!(child_organisation: @absorbing_organisation) + end + end + merging_organisation.child_organisation_relationships.each do |child_organisation_relationship| + if child_relationship_exists_on_absorbing_organisation?(child_organisation_relationship) + child_organisation_relationship.destroy! + else + child_organisation_relationship.update!(parent_organisation: @absorbing_organisation) + end + end + end + end + + def merge_users + @merging_organisations.each do |merging_organisation| + merging_organisation.users.update_all(organisation_id: @absorbing_organisation.id) + end + end + + def mark_organisations_as_merged + # @merging_organisations.update_all(merge_date: Time.zone.today) + end + + def merge_boolean_organisation_attribute(attribute) + @absorbing_organisation[attribute] ||= @merging_organisations.any? { |merging_organisation| merging_organisation[attribute] } + end + + def parent_relationship_exists_on_absorbing_organisation?(parent_organisation_relationship) + parent_organisation_relationship.parent_organisation == @absorbing_organisation || @absorbing_organisation.parent_organisation_relationships.where(parent_organisation: parent_organisation_relationship.parent_organisation).exists? + end + + def child_relationship_exists_on_absorbing_organisation?(child_organisation_relationship) + child_organisation_relationship.child_organisation == @absorbing_organisation || @absorbing_organisation.child_organisation_relationships.where(child_organisation: child_organisation_relationship.child_organisation).exists? + end +end diff --git a/spec/services/merge/merge_organisations_service_spec.rb b/spec/services/merge/merge_organisations_service_spec.rb new file mode 100644 index 000000000..480cfd657 --- /dev/null +++ b/spec/services/merge/merge_organisations_service_spec.rb @@ -0,0 +1,84 @@ +require "rails_helper" + +RSpec.describe Merge::MergeOrganisationsService do + subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids]) } + + let(:absorbing_organisation) do + create(:organisation, + holds_own_stock: false, + choice_based_lettings: false, + common_housing_register: true, + choice_allocation_policy: true) + end + let(:absorbing_organisation_user) { create(:user, organisation: absorbing_organisation) } + + describe "#call" do + context "when merging a single organisation into an existing organisation" do + let(:other_organisation) { create(:organisation) } + let(:merging_organisation) do + create(:organisation, + holds_own_stock: true, + choice_based_lettings: false, + common_housing_register: false, + choice_allocation_policy: true) + end + + let(:merging_organisation_ids) { [merging_organisation.id] } + let!(:merging_organisation_user) { create(:user, organisation: merging_organisation) } + let!(:merging_organisation_relationship) { create(:organisation_relationship, parent_organisation: merging_organisation) } + let!(:absorbing_organisation_relationship) { create(:organisation_relationship, parent_organisation: absorbing_organisation) } + let!(:absorbing_and_merging_organisation_relationship) { create(:organisation_relationship, parent_organisation: absorbing_organisation, child_organisation: merging_organisation) } + let!(:duplicate_merging_organisation_relationship) { create(:organisation_relationship, parent_organisation: merging_organisation, child_organisation: other_organisation) } + let!(:duplicate_absorbing_organisation_relationship) { create(:organisation_relationship, parent_organisation: absorbing_organisation, child_organisation: other_organisation) } + + before do + OrganisationRentPeriod.create!(organisation: absorbing_organisation, rent_period: 1) + OrganisationRentPeriod.create!(organisation: absorbing_organisation, rent_period: 3) + OrganisationRentPeriod.create!(organisation: merging_organisation, rent_period: 1) + OrganisationRentPeriod.create!(organisation: merging_organisation, rent_period: 2) + merge_organisations_service.call + end + + it "moves the users from merging organisation to absorbing organisation" do + merging_organisation_user.reload + expect(merging_organisation_user.organisation).to eq(absorbing_organisation) + end + + xit "sets merge date on merged organisation" do + expect(merging_organisation.merge_date).to eq(Time.zone.today) + end + + it "combines organisation data" do + absorbing_organisation.reload + expect(absorbing_organisation.holds_own_stock).to eq(true) + expect(absorbing_organisation.choice_based_lettings).to eq(false) + expect(absorbing_organisation.common_housing_register).to eq(true) + expect(absorbing_organisation.choice_allocation_policy).to eq(true) + # expect(absorbing_organisation.cbl_proportion_percentage).to eq(0) + # expect(absorbing_organisation.enter_affordable_logs).to eq(true) + # expect(absorbing_organisation.owns_affordable_logs).to eq(true) + # expect(absorbing_organisation.general_needs_units).to eq(2) + # expect(absorbing_organisation.supported_housing_units).to eq(2) + # expect(absorbing_organisation.unspecified_units).to eq(2) + end + + it "combines organisation rent periods" do + absorbing_organisation.reload + expect(absorbing_organisation.rent_periods.count).to eq(3) + expect(absorbing_organisation.rent_periods).to include(1) + expect(absorbing_organisation.rent_periods).to include(2) + expect(absorbing_organisation.rent_periods).to include(3) + end + + it "combines organisation relationships" do + absorbing_organisation.reload + expect(absorbing_organisation.child_organisations).to include(other_organisation) + expect(absorbing_organisation.child_organisations).to include(absorbing_organisation_relationship.child_organisation) + expect(absorbing_organisation.child_organisations).to include(merging_organisation_relationship.child_organisation) + expect(absorbing_organisation.child_organisations).not_to include(merging_organisation) + expect(absorbing_organisation.parent_organisations.count).to eq(0) + expect(absorbing_organisation.child_organisations.count).to eq(3) + end + end + end +end