Browse Source
# Conflicts: # app/models/form/lettings/pages/stock_owner.rb # app/models/form/lettings/questions/stock_owner.rb # app/models/form/sales/pages/organisation.rb # app/models/form/sales/questions/owning_organisation_id.rbpull/1830/head
55 changed files with 1541 additions and 94 deletions
@ -0,0 +1,57 @@
|
||||
module Imports |
||||
class ImportReportService |
||||
def initialize(storage_service, institutions_csv, logger = Rails.logger) |
||||
@storage_service = storage_service |
||||
@logger = logger |
||||
@institutions_csv = institutions_csv |
||||
end |
||||
|
||||
BYTE_ORDER_MARK = "\uFEFF".freeze # Required to ensure Excel always reads CSV as UTF-8 |
||||
|
||||
def create_reports(report_suffix) |
||||
generate_missing_data_coordinators_report(report_suffix) |
||||
generate_logs_report(report_suffix) |
||||
end |
||||
|
||||
def generate_missing_data_coordinators_report(report_suffix) |
||||
report_csv = "Organisation ID,Old Organisation ID,Organisation Name\n" |
||||
organisations = @institutions_csv.map { |row| Organisation.find_by(name: row[0]) }.compact |
||||
organisations.each do |organisation| |
||||
if organisation.users.none? { |user| user.data_coordinator? && user.active? } |
||||
report_csv += "#{organisation.id},#{organisation.old_visible_id},#{organisation.name}\n" |
||||
end |
||||
end |
||||
|
||||
report_name = "OrganisationsWithoutDataCoordinators_#{report_suffix}" |
||||
@storage_service.write_file(report_name, BYTE_ORDER_MARK + report_csv) |
||||
|
||||
@logger.info("Missing data coordinators report available in s3 import bucket at #{report_name}") |
||||
end |
||||
|
||||
def generate_logs_report(report_suffix) |
||||
Rails.logger.info("Generating migrated logs report") |
||||
|
||||
rep = CSV.generate do |report| |
||||
headers = ["Institution name", "Id", "Old Completed lettings logs", "Old In progress lettings logs", "Old Completed sales logs", "Old In progress sales logs", "New Completed lettings logs", "New In Progress lettings logs", "New Completed sales logs", "New In Progress sales logs"] |
||||
report << headers |
||||
|
||||
@institutions_csv.each do |row| |
||||
name = row[0] |
||||
organisation = Organisation.find_by(name:) |
||||
next unless organisation |
||||
|
||||
completed_sales_logs = organisation.owned_sales_logs.where(status: "completed").count |
||||
in_progress_sales_logs = organisation.owned_sales_logs.where(status: "in_progress").count |
||||
completed_lettings_logs = organisation.owned_lettings_logs.where(status: "completed").count |
||||
in_progress_lettings_logs = organisation.owned_lettings_logs.where(status: "in_progress").count |
||||
report << row.push(completed_lettings_logs, in_progress_lettings_logs, completed_sales_logs, in_progress_sales_logs) |
||||
end |
||||
end |
||||
|
||||
report_name = "MigratedLogsReport_#{report_suffix}" |
||||
@storage_service.write_file(report_name, BYTE_ORDER_MARK + rep) |
||||
|
||||
@logger.info("Logs report available in s3 import bucket at #{report_name}") |
||||
end |
||||
end |
||||
end |
||||
@ -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,30 @@
|
||||
<div class="app-filter-layout__filter"> |
||||
<div class="app-filter"> |
||||
<div class="app-filter__header"> |
||||
<h2 class="govuk-heading-m">Filters</h2> |
||||
</div> |
||||
|
||||
<div class="app-filter__content"> |
||||
<%= form_with url: scheme_locations_path(@scheme), html: { method: :get } do |f| %> |
||||
<div class="govuk-grid-row" style="white-space: nowrap"> |
||||
<p class="govuk-grid-column-one-half"> |
||||
<%= filters_applied_text(@filter_type) %> |
||||
</p> |
||||
<p class="govuk-!-text-align-right govuk-grid-column-one-half"> |
||||
<%= reset_filters_link(@filter_type, { scheme_id: @scheme.id }) %> |
||||
</p> |
||||
</div> |
||||
|
||||
<%= render partial: "filters/checkbox_filter", |
||||
locals: { |
||||
f:, |
||||
options: location_status_filters, |
||||
label: "Status", |
||||
category: "status", |
||||
} %> |
||||
|
||||
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-bottom-0" %> |
||||
<% end %> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
@ -0,0 +1,6 @@
|
||||
desc "Alter incref values for non imported lettings logs in the database" |
||||
task correct_incref_values: :environment do |
||||
LettingsLog.where(old_id: nil, net_income_known: 0).update!(incref: 0) |
||||
LettingsLog.where(old_id: nil, net_income_known: 1).update!(incref: 2) |
||||
LettingsLog.where(old_id: nil, net_income_known: 2).update!(incref: 1) |
||||
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,36 @@
|
||||
require "rails_helper" |
||||
require "rake" |
||||
|
||||
RSpec.describe "correct_incref_values" do |
||||
describe ":correct_incref_values", type: :task do |
||||
subject(:task) { Rake::Task["correct_incref_values"] } |
||||
|
||||
before do |
||||
Rake.application.rake_require("tasks/correct_incref_values") |
||||
Rake::Task.define_task(:environment) |
||||
task.reenable |
||||
end |
||||
|
||||
context "when the rake task is run" do |
||||
let!(:lettings_log) { create(:lettings_log, :completed) } |
||||
|
||||
it "updates lettings logs with net_income_known 0 (yes) to have incref 0 (no)" do |
||||
lettings_log.update!(net_income_known: 0, incref: nil) |
||||
task.invoke |
||||
expect(lettings_log.reload.incref).to eq(0) |
||||
end |
||||
|
||||
it "updates lettings logs with net_income_known 1 (no) to have incref 2 (don't know)" do |
||||
lettings_log.update!(net_income_known: 1, incref: nil) |
||||
task.invoke |
||||
expect(lettings_log.reload.incref).to eq(2) |
||||
end |
||||
|
||||
it "updates lettings logs with net_income_known 2 (prefers not to say) to have incref 1 (yes)" do |
||||
lettings_log.update!(net_income_known: 2, incref: nil) |
||||
task.invoke |
||||
expect(lettings_log.reload.incref).to eq(1) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
@ -0,0 +1,44 @@
|
||||
require "rails_helper" |
||||
require "rake" |
||||
|
||||
describe "full import", type: :task do |
||||
let(:instance_name) { "paas_import_instance" } |
||||
let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) } |
||||
let(:storage_service) { instance_double(Storage::S3Service) } |
||||
let(:orgs_list) { "Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1.zip,0,0,0,0\norg2,2.zip,0,0,0,0" } |
||||
|
||||
before do |
||||
allow(Storage::S3Service).to receive(:new).and_return(storage_service) |
||||
allow(storage_service).to receive(:write_file).and_return(nil) |
||||
allow(storage_service).to receive(:get_file_io).and_return(orgs_list) |
||||
allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service) |
||||
allow(ENV).to receive(:[]) |
||||
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name) |
||||
end |
||||
|
||||
describe "import:generate_reports" do |
||||
subject(:task) { Rake::Task["import:generate_reports"] } |
||||
|
||||
before do |
||||
Rake.application.rake_require("tasks/full_import") |
||||
Rake::Task.define_task(:environment) |
||||
task.reenable |
||||
end |
||||
|
||||
context "when generating report" do |
||||
let(:import_report_service) { instance_double(Imports::ImportReportService) } |
||||
|
||||
before do |
||||
allow(Imports::ImportReportService).to receive(:new).and_return(import_report_service) |
||||
end |
||||
|
||||
it "creates a report using given organisation csv" do |
||||
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name) |
||||
expect(Imports::ImportReportService).to receive(:new).with(storage_service, CSV.parse(orgs_list, headers: true)) |
||||
expect(import_report_service).to receive(:create_reports).with("some_name") |
||||
|
||||
task.invoke("some_name") |
||||
end |
||||
end |
||||
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,70 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Imports::ImportReportService do |
||||
subject(:report_service) { described_class.new(storage_service, institutions_csv) } |
||||
|
||||
let(:storage_service) { instance_double(Storage::S3Service) } |
||||
|
||||
describe "#generate_missing_data_coordinators_report" do |
||||
context "when all organisations have data coordinators" do |
||||
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") } |
||||
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) } |
||||
|
||||
before do |
||||
create(:user, :data_coordinator, organisation:) |
||||
end |
||||
|
||||
it "writes an empty organisations without a data coordinators report" do |
||||
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n") |
||||
|
||||
report_service.generate_missing_data_coordinators_report("report_suffix.csv") |
||||
end |
||||
end |
||||
|
||||
context "when some organisations have no data coordinators" do |
||||
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") } |
||||
let!(:organisation2) { create(:organisation, old_visible_id: "2", name: "org2") } |
||||
let!(:organisation3) { create(:organisation, old_visible_id: "3", name: "org3") } |
||||
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3\norg2,2,5,6,5,7\norg3,3,5,6,5,7", headers: true) } |
||||
|
||||
before do |
||||
create(:user, :data_coordinator, organisation:) |
||||
end |
||||
|
||||
it "writes an empty organisations without a data coordinators report" do |
||||
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n#{organisation2.id},2,org2\n#{organisation3.id},3,org3\n") |
||||
|
||||
report_service.generate_missing_data_coordinators_report("report_suffix.csv") |
||||
end |
||||
end |
||||
|
||||
context "when organisation has an inactive data coordinator" do |
||||
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") } |
||||
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) } |
||||
|
||||
before do |
||||
create(:user, :data_coordinator, organisation:, active: false) |
||||
end |
||||
|
||||
it "includes that organisation in the data coordinators report" do |
||||
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n#{organisation.id},1,org1\n") |
||||
|
||||
report_service.generate_missing_data_coordinators_report("report_suffix.csv") |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "#generate_logs_report" do |
||||
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3\norg2,2,5,6,5,7", headers: true) } |
||||
|
||||
before do |
||||
create(:organisation, old_visible_id: "1", name: "org1") |
||||
create(:organisation, old_visible_id: "2", name: "org2") |
||||
end |
||||
|
||||
it "generates a report with imported logs" do |
||||
expect(storage_service).to receive(:write_file).with("MigratedLogsReport_report_suffix.csv", "\uFEFFInstitution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs,New Completed lettings logs,New In Progress lettings logs,New Completed sales logs,New In Progress sales logs\norg1,1,2,1,4,3,0,0,0,0\norg2,2,5,6,5,7,0,0,0,0\n") |
||||
report_service.generate_logs_report("report_suffix.csv") |
||||
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