Browse Source
* Create merge_organisations_service * Refactor tests * update schemes merge * rename scope * merge letings logs * Merge sales logs * refactor merge organisations service * Rollback transaction if there's an error merging orgs * Add logging * add merge_organisations rake task * mark organisations as merged * update rake task * Update rake task add tests for multiple merging orgs * Add more tests for merging relationships * Update merge logging * set absorbing organisation relationshipCLDC-2105-merge-orgs-owning-org-dropdown
kosiakkatrina
1 year ago
committed by
GitHub
9 changed files with 514 additions and 6 deletions
@ -0,0 +1,131 @@ |
|||||||
|
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 |
||||||
|
ActiveRecord::Base.transaction do |
||||||
|
@merged_users = {} |
||||||
|
@merged_schemes = {} |
||||||
|
merge_organisation_details |
||||||
|
@merging_organisations.each do |merging_organisation| |
||||||
|
merge_rent_periods(merging_organisation) |
||||||
|
merge_organisation_relationships(merging_organisation) |
||||||
|
merge_users(merging_organisation) |
||||||
|
merge_schemes_and_locations(merging_organisation) |
||||||
|
merge_lettings_logs(merging_organisation) |
||||||
|
merge_sales_logs(merging_organisation) |
||||||
|
mark_organisation_as_merged(merging_organisation) |
||||||
|
end |
||||||
|
@absorbing_organisation.save! |
||||||
|
log_success_message |
||||||
|
rescue ActiveRecord::RecordInvalid => e |
||||||
|
Rails.logger.error("Organisation merge failed with: #{e.message}") |
||||||
|
raise ActiveRecord::Rollback |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def merge_organisation_details |
||||||
|
@absorbing_organisation.holds_own_stock = merge_boolean_organisation_attribute("holds_own_stock") |
||||||
|
end |
||||||
|
|
||||||
|
def merge_rent_periods(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 |
||||||
|
|
||||||
|
def merge_organisation_relationships(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 |
||||||
|
|
||||||
|
def merge_users(merging_organisation) |
||||||
|
@merged_users[merging_organisation.name] = merging_organisation.users.map { |user| { name: user.name, email: user.email } } |
||||||
|
merging_organisation.users.update_all(organisation_id: @absorbing_organisation.id) |
||||||
|
end |
||||||
|
|
||||||
|
def merge_schemes_and_locations(merging_organisation) |
||||||
|
@merged_schemes[merging_organisation.name] = [] |
||||||
|
merging_organisation.owned_schemes.each do |scheme| |
||||||
|
next if scheme.deactivated? |
||||||
|
|
||||||
|
new_scheme = Scheme.create!(scheme.attributes.except("id", "owning_organisation_id").merge(owning_organisation: @absorbing_organisation)) |
||||||
|
scheme.locations.each do |location| |
||||||
|
new_scheme.locations << Location.new(location.attributes.except("id", "scheme_id")) unless location.deactivated? |
||||||
|
end |
||||||
|
@merged_schemes[merging_organisation.name] << { name: new_scheme.service_name, code: new_scheme.id } |
||||||
|
SchemeDeactivationPeriod.create!(scheme:, deactivation_date: Time.zone.now) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def merge_lettings_logs(merging_organisation) |
||||||
|
merging_organisation.owned_lettings_logs.after_date(Time.zone.today).each do |lettings_log| |
||||||
|
if lettings_log.scheme.present? |
||||||
|
scheme_to_set = @absorbing_organisation.owned_schemes.find_by(service_name: lettings_log.scheme.service_name) |
||||||
|
location_to_set = scheme_to_set.locations.find_by(name: lettings_log.location&.name, postcode: lettings_log.location&.postcode) |
||||||
|
|
||||||
|
lettings_log.scheme = scheme_to_set if scheme_to_set.present? |
||||||
|
lettings_log.location = location_to_set if location_to_set.present? |
||||||
|
end |
||||||
|
lettings_log.owning_organisation = @absorbing_organisation |
||||||
|
lettings_log.save! |
||||||
|
end |
||||||
|
merging_organisation.managed_lettings_logs.after_date(Time.zone.today).each do |lettings_log| |
||||||
|
lettings_log.managing_organisation = @absorbing_organisation |
||||||
|
lettings_log.save! |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def merge_sales_logs(merging_organisation) |
||||||
|
merging_organisation.sales_logs.after_date(Time.zone.today).each do |sales_log| |
||||||
|
sales_log.update(owning_organisation: @absorbing_organisation) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def mark_organisation_as_merged(merging_organisation) |
||||||
|
merging_organisation.update(merge_date: Time.zone.today, absorbing_organisation: @absorbing_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
def log_success_message |
||||||
|
@merged_users.each do |organisation_name, users| |
||||||
|
Rails.logger.info("Merged users from #{organisation_name}:") |
||||||
|
users.each do |user| |
||||||
|
Rails.logger.info("\t#{user[:name]} (#{user[:email]})") |
||||||
|
end |
||||||
|
end |
||||||
|
@merged_schemes.each do |organisation_name, schemes| |
||||||
|
Rails.logger.info("New schemes from #{organisation_name}:") |
||||||
|
schemes.each do |scheme| |
||||||
|
Rails.logger.info("\t#{scheme[:name]} (S#{scheme[:code]})") |
||||||
|
end |
||||||
|
end |
||||||
|
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 |
@ -0,0 +1,12 @@ |
|||||||
|
namespace :merge do |
||||||
|
desc "Merge organisations into one" |
||||||
|
task :merge_organisations, %i[absorbing_organisation_id merging_organisation_ids] => :environment do |_task, args| |
||||||
|
absorbing_organisation_id = args[:absorbing_organisation_id] |
||||||
|
merging_organisation_ids = args[:merging_organisation_ids]&.split(" ")&.map(&:to_i) |
||||||
|
|
||||||
|
raise "Usage: rake merge:merge_organisations[absorbing_organisation_id, merging_organisation_ids]" if merging_organisation_ids.blank? || absorbing_organisation_id.blank? |
||||||
|
|
||||||
|
service = Merge::MergeOrganisationsService.new(absorbing_organisation_id:, merging_organisation_ids:) |
||||||
|
service.call |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,41 @@ |
|||||||
|
require "rails_helper" |
||||||
|
require "rake" |
||||||
|
|
||||||
|
RSpec.describe "emails" do |
||||||
|
describe ":merge_organisations", type: :task do |
||||||
|
subject(:task) { Rake::Task["merge:merge_organisations"] } |
||||||
|
|
||||||
|
let(:organisation) { create(:organisation) } |
||||||
|
let(:merging_organisation) { create(:organisation) } |
||||||
|
|
||||||
|
let(:merge_organisations_service) { Merge::MergeOrganisationsService.new(absorbing_organisation_id: organisation.id, merging_organisation_ids: [merging_organisation.id]) } |
||||||
|
|
||||||
|
before do |
||||||
|
allow(Merge::MergeOrganisationsService).to receive(:new).and_return(merge_organisations_service) |
||||||
|
allow(merge_organisations_service).to receive(:call).and_return(nil) |
||||||
|
Rake.application.rake_require("tasks/merge_organisations") |
||||||
|
Rake::Task.define_task(:environment) |
||||||
|
task.reenable |
||||||
|
end |
||||||
|
|
||||||
|
context "when the rake task is run" do |
||||||
|
it "raises an error when no parameters are given" do |
||||||
|
expect { task.invoke(nil) }.to raise_error(RuntimeError, "Usage: rake merge:merge_organisations[absorbing_organisation_id, merging_organisation_ids]") |
||||||
|
end |
||||||
|
|
||||||
|
it "raises an error when only absorbing organisation is given" do |
||||||
|
expect { task.invoke(1, nil) }.to raise_error(RuntimeError, "Usage: rake merge:merge_organisations[absorbing_organisation_id, merging_organisation_ids]") |
||||||
|
end |
||||||
|
|
||||||
|
it "raises an error when only merging organisations are given" do |
||||||
|
expect { task.invoke(nil, "1 2") }.to raise_error(RuntimeError, "Usage: rake merge:merge_organisations[absorbing_organisation_id, merging_organisation_ids]") |
||||||
|
end |
||||||
|
|
||||||
|
it "raises runs the service with correct organisation IDs" do |
||||||
|
expect(Merge::MergeOrganisationsService).to receive(:new).with(absorbing_organisation_id: 1, merging_organisation_ids: [2, 3]).once |
||||||
|
expect(merge_organisations_service).to receive(:call).once |
||||||
|
task.invoke(1, "2 3") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,323 @@ |
|||||||
|
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) { create(:organisation, holds_own_stock: false) } |
||||||
|
let(:absorbing_organisation_user) { create(:user, organisation: absorbing_organisation) } |
||||||
|
|
||||||
|
describe "#call" do |
||||||
|
context "when merging a single organisation into an existing organisation" do |
||||||
|
let(:merging_organisation) { create(:organisation, holds_own_stock: true, name: "fake org") } |
||||||
|
|
||||||
|
let(:merging_organisation_ids) { [merging_organisation.id] } |
||||||
|
let!(:merging_organisation_user) { create(:user, organisation: merging_organisation, name: "fake name", email: "fake@email.com") } |
||||||
|
|
||||||
|
it "moves the users from merging organisation to absorbing organisation" do |
||||||
|
expect(Rails.logger).to receive(:info).with("Merged users from fake org:") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tDanny Rojas (#{merging_organisation.data_protection_officers.first.email})") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tfake name (fake@email.com)") |
||||||
|
expect(Rails.logger).to receive(:info).with("New schemes from fake org:") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
merging_organisation_user.reload |
||||||
|
expect(merging_organisation_user.organisation).to eq(absorbing_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
it "sets merge date on merged organisation" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
merging_organisation.reload |
||||||
|
expect(merging_organisation.merge_date.to_date).to eq(Time.zone.today) |
||||||
|
expect(merging_organisation.absorbing_organisation_id).to eq(absorbing_organisation.id) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation data" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(absorbing_organisation.holds_own_stock).to eq(true) |
||||||
|
end |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.holds_own_stock).to eq(false) |
||||||
|
expect(merging_organisation.merge_date).to eq(nil) |
||||||
|
expect(merging_organisation.absorbing_organisation_id).to eq(nil) |
||||||
|
expect(merging_organisation_user.organisation).to eq(merging_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
context "and merging organisation rent periods" do |
||||||
|
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) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation rent periods" do |
||||||
|
expect(absorbing_organisation.rent_periods.count).to eq(2) |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
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 "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.rent_periods.count).to eq(2) |
||||||
|
expect(merging_organisation.rent_periods.count).to eq(2) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "and merging organisation relationships" do |
||||||
|
let(:other_organisation) { create(:organisation) } |
||||||
|
let!(:merging_organisation_relationship) { create(:organisation_relationship, parent_organisation: merging_organisation) } |
||||||
|
let!(:absorbing_organisation_relationship) { create(:organisation_relationship, parent_organisation: absorbing_organisation) } |
||||||
|
|
||||||
|
before do |
||||||
|
create(:organisation_relationship, parent_organisation: absorbing_organisation, child_organisation: merging_organisation) |
||||||
|
create(:organisation_relationship, parent_organisation: merging_organisation, child_organisation: other_organisation) |
||||||
|
create(:organisation_relationship, parent_organisation: absorbing_organisation, child_organisation: other_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation relationships" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(absorbing_organisation.child_organisations.count).to eq(3) |
||||||
|
expect(absorbing_organisation.child_organisations).to include(other_organisation) |
||||||
|
expect(absorbing_organisation.child_organisations).to include(merging_organisation) |
||||||
|
expect(absorbing_organisation.child_organisations).to include(absorbing_organisation_relationship.child_organisation) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "and merging organisation schemes and locations" do |
||||||
|
let!(:scheme) { create(:scheme, owning_organisation: merging_organisation) } |
||||||
|
let!(:location) { create(:location, scheme:) } |
||||||
|
let!(:deactivated_location) { create(:location, scheme:) } |
||||||
|
let!(:deactivated_scheme) { create(:scheme, owning_organisation: merging_organisation) } |
||||||
|
let!(:owned_lettings_log) { create(:lettings_log, :sh, scheme:, location:, startdate: Time.zone.tomorrow, owning_organisation: merging_organisation) } |
||||||
|
let!(:owned_lettings_log_no_location) { create(:lettings_log, :sh, scheme:, startdate: Time.zone.tomorrow, owning_organisation: merging_organisation) } |
||||||
|
|
||||||
|
before do |
||||||
|
create(:location, scheme:, name: "fake location", postcode: "A1 1AA") |
||||||
|
create(:location, scheme: deactivated_scheme) |
||||||
|
create(:scheme_deactivation_period, scheme: deactivated_scheme, deactivation_date: Time.zone.today - 1.month) |
||||||
|
create(:location_deactivation_period, location: deactivated_location, deactivation_date: Time.zone.today - 1.month) |
||||||
|
create(:lettings_log, scheme:, location:, startdate: Time.zone.yesterday) |
||||||
|
create(:lettings_log, startdate: Time.zone.tomorrow, managing_organisation: merging_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation schemes and locations" do |
||||||
|
expect(Rails.logger).to receive(:info).with("Merged users from fake org:") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tDanny Rojas (#{merging_organisation.data_protection_officers.first.email})") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tfake name (fake@email.com)") |
||||||
|
expect(Rails.logger).to receive(:info).with("New schemes from fake org:") |
||||||
|
expect(Rails.logger).to receive(:info).with(/\t#{scheme.service_name} \(S/) |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(absorbing_organisation.owned_schemes.count).to eq(1) |
||||||
|
expect(absorbing_organisation.owned_schemes.first.service_name).to eq(scheme.service_name) |
||||||
|
expect(absorbing_organisation.owned_schemes.first.locations.count).to eq(2) |
||||||
|
expect(absorbing_organisation.owned_schemes.first.locations.first.postcode).to eq(location.postcode) |
||||||
|
expect(scheme.scheme_deactivation_periods.count).to eq(1) |
||||||
|
expect(scheme.scheme_deactivation_periods.first.deactivation_date.to_date).to eq(Time.zone.today) |
||||||
|
end |
||||||
|
|
||||||
|
it "moves relevant logs and assigns the new scheme" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.owned_lettings_logs.count).to eq(2) |
||||||
|
expect(absorbing_organisation.managed_lettings_logs.count).to eq(1) |
||||||
|
expect(absorbing_organisation.owned_lettings_logs.find(owned_lettings_log.id).scheme).to eq(absorbing_organisation.owned_schemes.first) |
||||||
|
expect(absorbing_organisation.owned_lettings_logs.find(owned_lettings_log.id).location).to eq(absorbing_organisation.owned_schemes.first.locations.first) |
||||||
|
expect(absorbing_organisation.owned_lettings_logs.find(owned_lettings_log_no_location.id).scheme).to eq(absorbing_organisation.owned_schemes.first) |
||||||
|
expect(absorbing_organisation.owned_lettings_logs.find(owned_lettings_log_no_location.id).location).to eq(nil) |
||||||
|
end |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.owned_schemes.count).to eq(0) |
||||||
|
expect(scheme.scheme_deactivation_periods.count).to eq(0) |
||||||
|
expect(owned_lettings_log.owning_organisation).to eq(merging_organisation) |
||||||
|
expect(owned_lettings_log_no_location.owning_organisation).to eq(merging_organisation) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "and merging sales logs" do |
||||||
|
let!(:sales_log) { create(:sales_log, saledate: Time.zone.tomorrow, owning_organisation: merging_organisation) } |
||||||
|
|
||||||
|
before do |
||||||
|
create(:sales_log, saledate: Time.zone.yesterday, owning_organisation: merging_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
it "moves relevant logs" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(SalesLog.filter_by_owning_organisation(absorbing_organisation).count).to eq(1) |
||||||
|
expect(SalesLog.filter_by_owning_organisation(absorbing_organisation).first).to eq(sales_log) |
||||||
|
end |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(absorbing_organisation.sales_logs.count).to eq(0) |
||||||
|
expect(sales_log.owning_organisation).to eq(merging_organisation) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when merging a multiple organisations into an existing organisation" do |
||||||
|
let(:merging_organisation) { create(:organisation, holds_own_stock: true, name: "fake org") } |
||||||
|
let(:merging_organisation_too) { create(:organisation, holds_own_stock: true, name: "second org") } |
||||||
|
|
||||||
|
let(:merging_organisation_ids) { [merging_organisation.id, merging_organisation_too.id] } |
||||||
|
let!(:merging_organisation_user) { create(:user, organisation: merging_organisation, name: "fake name", email: "fake@email.com") } |
||||||
|
|
||||||
|
before do |
||||||
|
create_list(:user, 5, organisation: merging_organisation_too) |
||||||
|
end |
||||||
|
|
||||||
|
it "moves the users from merging organisations to absorbing organisation" do |
||||||
|
expect(Rails.logger).to receive(:info).with("Merged users from fake org:") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tDanny Rojas (#{merging_organisation.data_protection_officers.first.email})") |
||||||
|
expect(Rails.logger).to receive(:info).with("\tfake name (fake@email.com)") |
||||||
|
expect(Rails.logger).to receive(:info).with("Merged users from second org:") |
||||||
|
expect(Rails.logger).to receive(:info).with(/\tDanny Rojas/).exactly(6).times |
||||||
|
expect(Rails.logger).to receive(:info).with("New schemes from fake org:") |
||||||
|
expect(Rails.logger).to receive(:info).with("New schemes from second org:") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
merging_organisation_user.reload |
||||||
|
expect(merging_organisation_user.organisation).to eq(absorbing_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
it "sets merge date and absorbing organisation on merged organisations" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
merging_organisation.reload |
||||||
|
merging_organisation_too.reload |
||||||
|
expect(merging_organisation.merge_date.to_date).to eq(Time.zone.today) |
||||||
|
expect(merging_organisation.absorbing_organisation_id).to eq(absorbing_organisation.id) |
||||||
|
expect(merging_organisation_too.merge_date.to_date).to eq(Time.zone.today) |
||||||
|
expect(merging_organisation_too.absorbing_organisation_id).to eq(absorbing_organisation.id) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation data" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
expect(absorbing_organisation.holds_own_stock).to eq(true) |
||||||
|
end |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.holds_own_stock).to eq(false) |
||||||
|
expect(merging_organisation.merge_date).to eq(nil) |
||||||
|
expect(merging_organisation.absorbing_organisation_id).to eq(nil) |
||||||
|
expect(merging_organisation_user.organisation).to eq(merging_organisation) |
||||||
|
end |
||||||
|
|
||||||
|
context "and merging organisation relationships" do |
||||||
|
let(:other_organisation) { create(:organisation) } |
||||||
|
let!(:merging_organisation_relationship) { create(:organisation_relationship, parent_organisation: merging_organisation) } |
||||||
|
let!(:absorbing_organisation_relationship) { create(:organisation_relationship, parent_organisation: absorbing_organisation) } |
||||||
|
|
||||||
|
before do |
||||||
|
create(:organisation_relationship, parent_organisation: merging_organisation, child_organisation: absorbing_organisation) |
||||||
|
create(:organisation_relationship, parent_organisation: merging_organisation, child_organisation: other_organisation) |
||||||
|
create(:organisation_relationship, parent_organisation: absorbing_organisation, child_organisation: other_organisation) |
||||||
|
create(:organisation_relationship, parent_organisation: merging_organisation, child_organisation: merging_organisation_too) |
||||||
|
end |
||||||
|
|
||||||
|
it "combines organisation relationships" do |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
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).not_to include(merging_organisation) |
||||||
|
expect(absorbing_organisation.child_organisations).not_to include(merging_organisation_too) |
||||||
|
expect(absorbing_organisation.parent_organisations).not_to include(merging_organisation_too) |
||||||
|
expect(absorbing_organisation.parent_organisations.count).to eq(0) |
||||||
|
expect(absorbing_organisation.child_organisations.count).to eq(3) |
||||||
|
end |
||||||
|
|
||||||
|
it "rolls back if there's an error" do |
||||||
|
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids)) |
||||||
|
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation) |
||||||
|
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid) |
||||||
|
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid") |
||||||
|
merge_organisations_service.call |
||||||
|
|
||||||
|
absorbing_organisation.reload |
||||||
|
merging_organisation.reload |
||||||
|
expect(absorbing_organisation.child_organisations.count).to eq(2) |
||||||
|
expect(absorbing_organisation.parent_organisations.count).to eq(1) |
||||||
|
expect(absorbing_organisation.child_organisations).to include(other_organisation) |
||||||
|
expect(absorbing_organisation.parent_organisations).to include(merging_organisation) |
||||||
|
expect(absorbing_organisation.child_organisations).to include(absorbing_organisation_relationship.child_organisation) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue