diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 087314863..aeed98d9e 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -52,6 +52,7 @@ module FiltersHelper "incomplete" => "Incomplete", "active" => "Active", "deactivating_soon" => "Deactivating soon", + "activating_soon" => "Activating soon", "reactivating_soon" => "Reactivating soon", "deactivated" => "Deactivated", }.freeze diff --git a/app/models/location.rb b/app/models/location.rb index 65e0466b3..64272d549 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -21,9 +21,9 @@ class Location < ApplicationRecord scope :search_by_postcode, ->(postcode) { where("REPLACE(postcode, ' ', '') ILIKE ?", "%#{postcode.delete(' ')}%") } scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) } - scope :started, -> { where("startdate <= ?", Time.zone.today).or(where(startdate: nil)) } + scope :started, -> { where("locations.startdate <= ?", Time.zone.today).or(where(startdate: nil)) } scope :active, -> { where(confirmed: true).and(started) } - scope :started_in_2_weeks, -> { where("startdate <= ?", Time.zone.today + 2.weeks).or(where(startdate: nil)) } + scope :started_in_2_weeks, -> { where("locations.startdate <= ?", Time.zone.today + 2.weeks).or(where(startdate: nil)) } scope :active_in_2_weeks, -> { where(confirmed: true).and(started_in_2_weeks) } scope :confirmed, -> { where(confirmed: true) } scope :unconfirmed, -> { where.not(confirmed: true) } @@ -122,9 +122,7 @@ class Location < ApplicationRecord end def available_from - return startdate if startdate.present? - - FormHandler.instance.earliest_open_collection_start_date(now: created_at) + startdate || FormHandler.instance.earliest_open_collection_start_date(now: created_at) end def open_deactivation diff --git a/app/models/organisation.rb b/app/models/organisation.rb index 077f0413e..da6a92d0d 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -25,6 +25,11 @@ class Organisation < ApplicationRecord ids << id end + absorbed_organisations.each do |organisation| + ids.concat(organisation.stock_owners.pluck(:id)) + ids << organisation.id if organisation.holds_own_stock? + end + ids.concat(stock_owners.pluck(:id)) Organisation.where(id: ids) diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 4345b9694..fd330f5c5 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -33,6 +33,8 @@ class SalesLog < Log before_validation :set_derived_fields! before_validation :process_uprn_change!, if: :should_process_uprn_change? + belongs_to :managing_organisation, class_name: "Organisation", optional: true + scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } scope :filter_by_purchaser_code, ->(purchid) { where("purchid ILIKE ?", "%#{purchid}%") } scope :search_by, lambda { |param| diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 9d760998d..00db3924d 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -65,11 +65,16 @@ class Scheme < ApplicationRecord .where("scheme_deactivation_periods.reactivation_date > ?", Time.zone.now) } + scope :activating_soon, lambda { + where("startdate > ?", Time.zone.now) + } + scope :active_status, lambda { where.not(id: joins(:scheme_deactivation_periods).reactivating_soon.pluck(:id)) .where.not(id: joins(:scheme_deactivation_periods).deactivated.pluck(:id)) .where.not(id: incomplete.pluck(:id)) .where.not(id: joins(:scheme_deactivation_periods).deactivating_soon.pluck(:id)) + .where.not(id: activating_soon.pluck(:id)) } validate :validate_confirmed @@ -243,7 +248,7 @@ class Scheme < ApplicationRecord end def validate_confirmed - required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type] + required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type startdate] if confirmed == true required_attributes.any? do |attribute| @@ -262,7 +267,7 @@ class Scheme < ApplicationRecord end def available_from - FormHandler.instance.earliest_open_collection_start_date(now: created_at) + startdate || FormHandler.instance.earliest_open_collection_start_date(now: created_at) end def open_deactivation @@ -282,6 +287,7 @@ class Scheme < ApplicationRecord return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date return :reactivating_soon if last_deactivation_before(date)&.reactivation_date.present? && date < last_deactivation_before(date).reactivation_date + return :activating_soon if startdate.present? && date < startdate :active end diff --git a/app/models/validations/setup_validations.rb b/app/models/validations/setup_validations.rb index 744cc5ade..adfcfe861 100644 --- a/app/models/validations/setup_validations.rb +++ b/app/models/validations/setup_validations.rb @@ -14,8 +14,6 @@ module Validations::SetupValidations unless record.startdate.between?(first_collection_start_date, current_collection_end_date) record.errors.add :startdate, startdate_validation_error_message end - - validate_merged_organisations_start_date(record) end def validate_organisation(record) @@ -54,6 +52,16 @@ module Validations::SetupValidations end end + def validate_merged_organisations_start_date(record) + return unless record.startdate && date_valid?("startdate", record) + + return add_same_merge_organisation_error(record) if record.owning_organisation == record.managing_organisation + return add_same_merge_error(record) if organisations_belong_to_same_merge?(record.owning_organisation, record.managing_organisation) + + add_merged_organisations_errors(record) + add_absorbing_organisations_errors(record) + end + def validate_irproduct_other(record) if intermediate_product_rent_type?(record) && record.irproduct_other.blank? record.errors.add :irproduct_other, I18n.t("validations.setup.intermediate_rent_product_name.blank") @@ -134,14 +142,6 @@ private record.rent_type == 5 end - def validate_merged_organisations_start_date(record) - return add_same_merge_organisation_error(record) if record.owning_organisation == record.managing_organisation - return add_same_merge_error(record) if organisations_belong_to_same_merge?(record.owning_organisation, record.managing_organisation) - - add_merged_organisations_errors(record) - add_absorbing_organisations_errors(record) - end - def add_same_merge_organisation_error(record) if merged_owning_organisation_inactive?(record) record.errors.add :startdate, I18n.t("validations.setup.startdate.invalid_merged_organisations_start_date.same_organisation", diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb index 585ec7c93..25b00302c 100644 --- a/app/services/bulk_upload/lettings/year2023/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb @@ -540,11 +540,11 @@ private def validate_created_by_related return unless created_by + return if created_by.organisation == owning_organisation || created_by.organisation == managing_organisation + return if created_by.organisation == owning_organisation&.absorbing_organisation || created_by.organisation == managing_organisation&.absorbing_organisation - unless (created_by.organisation == owning_organisation) || (created_by.organisation == managing_organisation) - block_log_creation! - errors.add(:field_3, "User must be related to owning organisation or managing organisation") - end + block_log_creation! + errors.add(:field_3, "User must be related to owning organisation or managing organisation") end def created_by diff --git a/app/services/bulk_upload/sales/year2023/row_parser.rb b/app/services/bulk_upload/sales/year2023/row_parser.rb index 6ce207abf..c83c9161a 100644 --- a/app/services/bulk_upload/sales/year2023/row_parser.rb +++ b/app/services/bulk_upload/sales/year2023/row_parser.rb @@ -1195,11 +1195,10 @@ private def validate_created_by_related return unless created_by + return if created_by.organisation == owning_organisation || created_by.organisation == owning_organisation&.absorbing_organisation - unless created_by.organisation == owning_organisation - block_log_creation! - errors.add(:field_2, "User must be related to owning organisation", category: :setup) - end + block_log_creation! + errors.add(:field_2, "User must be related to owning organisation", category: :setup) end def setup_question?(question) diff --git a/app/services/merge/merge_organisations_service.rb b/app/services/merge/merge_organisations_service.rb index 1599db5fa..a6a148b21 100644 --- a/app/services/merge/merge_organisations_service.rb +++ b/app/services/merge/merge_organisations_service.rb @@ -69,9 +69,9 @@ private merging_organisation.owned_schemes.each do |scheme| next if scheme.deactivated? - new_scheme = Scheme.create!(scheme.attributes.except("id", "owning_organisation_id", "old_id", "old_visible_id").merge(owning_organisation: @absorbing_organisation)) + new_scheme = Scheme.create!(scheme.attributes.except("id", "owning_organisation_id", "old_id", "old_visible_id").merge(owning_organisation: @absorbing_organisation, startdate: @merge_date)) scheme.locations.each do |location| - new_scheme.locations << Location.new(location.attributes.except("id", "scheme_id", "old_id", "old_visible_id")) unless location.deactivated? + new_scheme.locations << Location.new(location.attributes.except("id", "scheme_id", "old_id", "old_visible_id").merge(startdate: [location&.startdate, @merge_date].compact.max)) unless location.deactivated? end @merged_schemes[merging_organisation.name] << { name: new_scheme.service_name, code: new_scheme.id } SchemeDeactivationPeriod.create!(scheme:, deactivation_date: @merge_date) diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 3dc3a70b3..f105cb9d5 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -17,16 +17,6 @@
  • Monday to Friday, 9am to 5:30pm
    (except public holidays)
  • - -
    -

    Email

    - -

    Helpful links

    diff --git a/db/migrate/20231121131725_add_sales_managing_organisation.rb b/db/migrate/20231121131725_add_sales_managing_organisation.rb new file mode 100644 index 000000000..f4085414a --- /dev/null +++ b/db/migrate/20231121131725_add_sales_managing_organisation.rb @@ -0,0 +1,7 @@ +class AddSalesManagingOrganisation < ActiveRecord::Migration[7.0] + def change + change_table :sales_logs, bulk: true do |t| + t.references :managing_organisation, class_name: "Organisation" + end + end +end diff --git a/db/migrate/20231204101105_add_startdate_to_schemes.rb b/db/migrate/20231204101105_add_startdate_to_schemes.rb new file mode 100644 index 000000000..9299cb80a --- /dev/null +++ b/db/migrate/20231204101105_add_startdate_to_schemes.rb @@ -0,0 +1,5 @@ +class AddStartdateToSchemes < ActiveRecord::Migration[7.0] + def change + add_column :schemes, :startdate, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 7eda570d1..610f2f1a4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_10_23_142854) do +ActiveRecord::Schema[7.0].define(version: 2023_12_04_101105) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -624,8 +624,10 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_23_142854) do t.integer "creation_method", default: 1 t.integer "old_form_id" t.datetime "values_updated_at" + t.bigint "managing_organisation_id" t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id" t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id" + t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id" t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id" t.index ["updated_by_id"], name: "index_sales_logs_on_updated_by_id" @@ -659,6 +661,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_23_142854) do t.string "old_visible_id" t.integer "total_units" t.boolean "confirmed" + t.datetime "startdate" t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id" end diff --git a/lib/tasks/set_sales_managing_organisation.rake b/lib/tasks/set_sales_managing_organisation.rake new file mode 100644 index 000000000..85e2ced22 --- /dev/null +++ b/lib/tasks/set_sales_managing_organisation.rake @@ -0,0 +1,4 @@ +desc "Set sales managing organisation id to owning organisation id" +task set_sales_managing_organisation: :environment do + SalesLog.where.not(owning_organisation_id: nil).update_all("managing_organisation_id = owning_organisation_id") +end diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index da4b17322..fec1ce53b 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/spec/helpers/locations_helper_spec.rb @@ -214,6 +214,15 @@ RSpec.describe LocationsHelper do expect(availability_attribute).to eq("Active from 1 April 2022") end + + context "when location was merged" do + it "displays merge date as availability date" do + location.update!(startdate: Time.zone.local(2022, 4, 16)) + availability_attribute = display_location_attributes(location).find { |x| x[:name] == "Availability" }[:value] + + expect(availability_attribute).to eq("Active from 16 April 2022") + end + end end context "with previous deactivations" do diff --git a/spec/helpers/schemes_helper_spec.rb b/spec/helpers/schemes_helper_spec.rb index 6aaa10260..ff3030932 100644 --- a/spec/helpers/schemes_helper_spec.rb +++ b/spec/helpers/schemes_helper_spec.rb @@ -303,6 +303,17 @@ RSpec.describe SchemesHelper do expect(display_scheme_attributes(scheme)).to eq(attributes) end end + + context "when scheme was merged from another organisation" do + before do + FactoryBot.create(:location, scheme:) + scheme.startdate = Time.zone.local(2023, 1, 5) + end + + it "returns correct availability" do + expect(display_scheme_attributes(scheme)).to include({ name: "Availability", value: "Active from 5 January 2023" }) + end + end end describe "edit_scheme_text" do diff --git a/spec/lib/tasks/set_sales_managing_organisation_spec.rb b/spec/lib/tasks/set_sales_managing_organisation_spec.rb new file mode 100644 index 000000000..c8e304d9f --- /dev/null +++ b/spec/lib/tasks/set_sales_managing_organisation_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" +require "rake" + +RSpec.describe "set_sales_managing_organisation" do + describe ":set_sales_managing_organisation", type: :task do + subject(:task) { Rake::Task["set_sales_managing_organisation"] } + + before do + Rake.application.rake_require("tasks/set_sales_managing_organisation") + Rake::Task.define_task(:environment) + task.reenable + end + + context "when the rake task is run" do + let!(:sales_log) { create(:sales_log, :completed, managing_organisation_id: nil) } + + it "updates sales log managing_organisation_id with owning_organisation_id" do + expect(sales_log.managing_organisation_id).to eq(nil) + expect(sales_log.status).to eq("completed") + task.invoke + sales_log.reload + expect(sales_log.managing_organisation_id).to eq(sales_log.owning_organisation_id) + expect(sales_log.status).to eq("completed") + end + + it "does not update sales log managing_organisation_id if owning_organisation_id is nil" do + sales_log.update!(owning_organisation_id: nil) + expect(sales_log.status).to eq("in_progress") + expect(sales_log.managing_organisation_id).to eq(nil) + task.invoke + sales_log.reload + expect(sales_log.managing_organisation_id).to eq(nil) + expect(sales_log.status).to eq("in_progress") + end + + it "skips validations" do + sales_log.saledate = Time.zone.local(2021, 3, 3) + sales_log.save!(validate: false) + expect(sales_log.managing_organisation_id).to eq(nil) + expect(sales_log.status).to eq("in_progress") + task.invoke + sales_log.reload + expect(sales_log.managing_organisation_id).to eq(sales_log.owning_organisation_id) + expect(sales_log.status).to eq("in_progress") + end + end + end +end diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb index cb9d74578..2f1036c1a 100644 --- a/spec/models/scheme_spec.rb +++ b/spec/models/scheme_spec.rb @@ -123,6 +123,7 @@ RSpec.describe Scheme, type: :model do let(:deactivated_scheme_2) { FactoryBot.create(:scheme) } let(:reactivating_soon_scheme) { FactoryBot.create(:scheme) } let(:reactivating_soon_scheme_2) { FactoryBot.create(:scheme) } + let(:activating_soon_scheme) { FactoryBot.create(:scheme, startdate: Time.zone.today + 1.week) } before do scheme.destroy! @@ -242,11 +243,18 @@ RSpec.describe Scheme, type: :model do expect(scheme.status).to eq(:deactivated) end - it "returns reactivating soon if the location has a future reactivation date" do + it "returns reactivating soon if the scheme has a future reactivation date" do FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 8), scheme:) scheme.save! expect(scheme.status).to eq(:reactivating_soon) end + + it "returns activating soon if the scheme has a future startdate" do + Timecop.freeze(2022, 6, 4) + scheme.startdate = Time.zone.local(2022, 7, 7) + scheme.save! + expect(scheme.status).to eq(:activating_soon) + end end context "when there have been previous deactivations" do @@ -283,12 +291,18 @@ RSpec.describe Scheme, type: :model do expect(scheme.status).to eq(:reactivating_soon) end - it "returns if the scheme had a deactivation during another deactivation" do + it "returns reactivating soon if the scheme had a deactivation during another deactivation" do Timecop.freeze(2022, 6, 4) FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 2), scheme:) scheme.save! expect(scheme.status).to eq(:reactivating_soon) end + + it "returns activating soon if the scheme has a future startdate" do + scheme.startdate = Time.zone.local(2022, 7, 7) + scheme.save! + expect(scheme.status).to eq(:activating_soon) + end end end diff --git a/spec/models/validations/setup_validations_spec.rb b/spec/models/validations/setup_validations_spec.rb index 2a05ecb77..763bf89b9 100644 --- a/spec/models/validations/setup_validations_spec.rb +++ b/spec/models/validations/setup_validations_spec.rb @@ -17,12 +17,14 @@ RSpec.describe Validations::SetupValidations do it "cannot be before the first collection window start date" do record.startdate = Time.zone.local(2021, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 21/22 or 22/23 collection years, which is between 1st April 2021 and 31st March 2023") end it "cannot be after the second collection window end date" do record.startdate = Time.zone.local(2023, 7, 1, 6) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 21/22 or 22/23 collection years, which is between 1st April 2021 and 31st March 2023") end end @@ -36,12 +38,14 @@ RSpec.describe Validations::SetupValidations do it "cannot be before the first collection window start date" do record.startdate = Time.zone.local(2022, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end it "cannot be after the second collection window end date" do record.startdate = Time.zone.local(2023, 7, 1, 6) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023") end end @@ -57,12 +61,14 @@ RSpec.describe Validations::SetupValidations do it "cannot be before the first collection window start date" do record.startdate = Time.zone.local(2022, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 or 23/24 collection years, which is between 1st April 2022 and 31st March 2024") end it "cannot be after the second collection window end date" do record.startdate = Time.zone.local(2024, 7, 1, 6) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 22/23 or 23/24 collection years, which is between 1st April 2022 and 31st March 2024") end end @@ -76,12 +82,14 @@ RSpec.describe Validations::SetupValidations do it "cannot be before the first collection window start date" do record.startdate = Time.zone.local(2023, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end it "cannot be after the second collection window end date" do record.startdate = Time.zone.local(2024, 7, 1, 6) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end end @@ -95,6 +103,7 @@ RSpec.describe Validations::SetupValidations do record.update!(startdate: nil) record.startdate = Time.zone.local(2023, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end @@ -103,6 +112,7 @@ RSpec.describe Validations::SetupValidations do record.save!(validate: false) record.startdate = Time.zone.local(2023, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).not_to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end end @@ -116,6 +126,7 @@ RSpec.describe Validations::SetupValidations do record.update!(startdate: nil) record.startdate = Time.zone.local(2023, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end @@ -124,6 +135,7 @@ RSpec.describe Validations::SetupValidations do record.save!(validate: false) record.startdate = Time.zone.local(2023, 1, 1) setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date within the 23/24 collection year, which is between 1st April 2023 and 31st March 2024") end end @@ -151,6 +163,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 3, 1) record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") end @@ -158,6 +171,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 1, 1) record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -167,6 +181,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 1, 1) record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Absorbing org became active on 1 February 2023.") end @@ -174,6 +189,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 2, 2) record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end @@ -182,6 +198,7 @@ RSpec.describe Validations::SetupValidations do absorbing_organisation.update!(available_from: nil) record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -191,6 +208,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 3, 1) record.managing_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") end @@ -198,6 +216,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 1, 1) record.managing_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -207,6 +226,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 1, 1) record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Absorbing org became active on 1 February 2023.") end @@ -214,6 +234,7 @@ RSpec.describe Validations::SetupValidations do record.startdate = Time.zone.local(2023, 2, 2) record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end @@ -222,6 +243,7 @@ RSpec.describe Validations::SetupValidations do absorbing_organisation.update!(available_from: nil) record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -232,6 +254,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") end @@ -240,6 +263,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -250,6 +274,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Absorbing org became active on 1 February 2023.") end @@ -258,6 +283,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end @@ -267,6 +293,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -277,6 +304,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 and Merged org became inactive on 2 February 2023 and were replaced by Absorbing org.") end @@ -285,6 +313,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -299,6 +328,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 became inactive on 2 February 2023 and was replaced by Absorbing org 2. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") end @@ -307,6 +337,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end @@ -321,6 +352,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation_2.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Absorbing org 2 became active on 1 February 2023, and Absorbing org became active on 1 February 2023.") end @@ -329,6 +361,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end @@ -338,6 +371,7 @@ RSpec.describe Validations::SetupValidations do record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) expect(record.errors["startdate"]).to be_empty end end diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb index 86e45ca2d..af713d29b 100644 --- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb @@ -1384,6 +1384,28 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do expect(parser).to be_block_log_creation end end + + context "when user's org has absorbed owning organisation" do + let(:merged_org) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } + let(:merged_org_stock_owner) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } + + let(:attributes) { { bulk_upload:, field_1: merged_org_stock_owner.old_visible_id, field_2: merged_org.old_visible_id, field_3: user.email } } + + before do + create(:organisation_relationship, parent_organisation: merged_org_stock_owner, child_organisation: merged_org) + merged_org.update!(absorbing_organisation: user.organisation, merge_date: Time.zone.today) + merged_org.reload + user.organisation.reload + end + + it "is permitted" do + parser = described_class.new(attributes) + + parser.valid? + expect(parser.errors.where(:field_1)).not_to be_present + expect(parser.errors.where(:field_3)).not_to be_present + end + end end describe "#field_2" do # managing org diff --git a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb index 0745274fc..408ce099b 100644 --- a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb @@ -417,6 +417,46 @@ RSpec.describe BulkUpload::Sales::Year2023::RowParser do expect(parser).to be_block_log_creation end end + + context "when user's org has absorbed owning organisation with stock owners" do + let(:merged_org) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } + let(:merged_org_stock_owner) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } + + let(:attributes) { { bulk_upload:, field_1: merged_org_stock_owner.old_visible_id } } + + before do + create(:organisation_relationship, parent_organisation: merged_org_stock_owner, child_organisation: merged_org) + merged_org.update!(absorbing_organisation: user.organisation, merge_date: Time.zone.today) + merged_org.reload + user.organisation.reload + end + + it "is permitted" do + parser.valid? + expect(parser.errors.where(:field_1)).not_to be_present + end + end + + context "when user's org has absorbed owning organisation" do + let(:merged_org) { create(:organisation, :with_old_visible_id, holds_own_stock: true) } + + let(:attributes) { { bulk_upload:, field_1: merged_org.old_visible_id, field_2: user.email } } + + before do + merged_org.update!(absorbing_organisation: user.organisation, merge_date: Time.zone.today) + merged_org.reload + user.organisation.reload + user.reload + end + + it "is permitted" do + parser = described_class.new(attributes) + + parser.valid? + expect(parser.errors.where(:field_1)).not_to be_present + expect(parser.errors.where(:field_2)).not_to be_present + end + end end describe "#field_2" do # username for created_by diff --git a/spec/services/merge/merge_organisations_service_spec.rb b/spec/services/merge/merge_organisations_service_spec.rb index b6168d57a..5f2cf5e83 100644 --- a/spec/services/merge/merge_organisations_service_spec.rb +++ b/spec/services/merge/merge_organisations_service_spec.rb @@ -318,21 +318,31 @@ RSpec.describe Merge::MergeOrganisationsService do 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(1) - 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.yesterday) + context "with multiple locations" do + let!(:location_without_startdate) { create(:location, scheme:, startdate: nil) } + let!(:location_with_past_startdate) { create(:location, scheme:, startdate: Time.zone.today - 2.months) } + let!(:location_with_future_startdate) { create(:location, scheme:, startdate: Time.zone.today + 2.months) } + + 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.startdate).to eq(Time.zone.yesterday) + expect(absorbing_organisation.owned_schemes.first.locations.count).to eq(4) + expect(absorbing_organisation.owned_schemes.first.locations.map(&:postcode)).to match_array([location, location_without_startdate, location_with_past_startdate, location_with_future_startdate].map(&:postcode)) + expect(absorbing_organisation.owned_schemes.first.locations.find_by(postcode: location_without_startdate.postcode).startdate).to eq(Time.zone.yesterday) + expect(absorbing_organisation.owned_schemes.first.locations.find_by(postcode: location_with_past_startdate.postcode).startdate).to eq(Time.zone.yesterday) + expect(absorbing_organisation.owned_schemes.first.locations.find_by(postcode: location_with_future_startdate.postcode).startdate).to eq(Time.zone.today + 2.months) + expect(scheme.scheme_deactivation_periods.count).to eq(1) + expect(scheme.scheme_deactivation_periods.first.deactivation_date.to_date).to eq(Time.zone.yesterday) + end end it "moves relevant logs and assigns the new scheme" do