diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 6d3524723..2c73acc06 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -103,6 +103,22 @@ class Scheme < ApplicationRecord scope :visible, -> { where(discarded_at: nil) } + scope :duplicate_sets, lambda { + scope = visible + .group(*DUPLICATE_SCHEME_ATTRIBUTES) + .where.not(scheme_type: nil) + .where.not(registered_under_care_act: nil) + .where.not(primary_client_group: nil) + .where.not(has_other_client_group: nil) + .where.not(secondary_client_group: nil).or(where(has_other_client_group: 0)) + .where.not(support_type: nil) + .where.not(intended_stay: nil) + .having( + "COUNT(*) > 1", + ) + scope.pluck("ARRAY_AGG(id)") + } + validate :validate_confirmed validate :validate_owning_organisation @@ -192,6 +208,8 @@ class Scheme < ApplicationRecord "Missing": "X", }.freeze + DUPLICATE_SCHEME_ATTRIBUTES = %w[scheme_type registered_under_care_act primary_client_group secondary_client_group has_other_client_group support_type intended_stay].freeze + enum arrangement_type: ARRANGEMENT_TYPE, _suffix: true def self.find_by_id_on_multiple_fields(scheme_id, location_id) diff --git a/spec/factories/scheme.rb b/spec/factories/scheme.rb index 7983bfa0a..5f4ad30bc 100644 --- a/spec/factories/scheme.rb +++ b/spec/factories/scheme.rb @@ -32,5 +32,14 @@ FactoryBot.define do confirmed { false } support_type { nil } end + trait :duplicate do + scheme_type { 4 } + registered_under_care_act { 1 } + primary_client_group { "O" } + secondary_client_group { "H" } + has_other_client_group { 1 } + support_type { 2 } + intended_stay { "M" } + end end end diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb index 9b3db15a4..277ebf65b 100644 --- a/spec/models/scheme_spec.rb +++ b/spec/models/scheme_spec.rb @@ -208,6 +208,125 @@ RSpec.describe Scheme, type: :model do end end end + + context "when getting list of duplicate schemes" do + let(:organisation) { create(:organisation) } + let!(:scheme) { create(:scheme, :duplicate, owning_organisation: organisation) } + let!(:duplicate_scheme) { create(:scheme, :duplicate, owning_organisation: organisation) } + let(:duplicate_sets) { described_class.duplicate_sets } + + it "returns a list of duplicates in the same organisation" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + + context "when there is a deleted duplicate scheme" do + before do + create(:scheme, :duplicate, discarded_at: Time.zone.now) + end + + it "does not return the deleted scheme as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different scheme_type" do + before do + create(:scheme, :duplicate, scheme_type: 7) + end + + it "does not return a scheme with a different scheme_type as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different registered_under_care_act" do + before do + create(:scheme, :duplicate, registered_under_care_act: 2) + end + + it "does not return a scheme with a different registered_under_care_act as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different primary_client_group" do + before do + create(:scheme, :duplicate, primary_client_group: "H") + end + + it "does not return a scheme with a different primary_client_group as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different secondary_client_group" do + before do + create(:scheme, :duplicate, secondary_client_group: "O") + end + + it "does not return a scheme with a different secondary_client_group as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different has_other_client_group" do + before do + create(:scheme, :duplicate, has_other_client_group: 0) + end + + it "does not return a scheme with a different has_other_client_group as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different support_type" do + before do + create(:scheme, :duplicate, support_type: 4) + end + + it "does not return a scheme with a different support_type as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with a different intended_stay" do + before do + create(:scheme, :duplicate, intended_stay: "P") + end + + it "does not return a scheme with a different intended_stay as a duplicate" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + + context "when there is a scheme with nil values for duplicate check fields" do + let!(:scheme) { build(:scheme, :duplicate, owning_organisation: organisation, scheme_type: nil, registered_under_care_act: nil, primary_client_group: nil, secondary_client_group: nil, has_other_client_group: nil, support_type: nil, intended_stay: nil).save(validate: false) } + let!(:duplicate_scheme) { build(:scheme, :duplicate, owning_organisation: organisation, scheme_type: nil, registered_under_care_act: nil, primary_client_group: nil, secondary_client_group: nil, has_other_client_group: nil, support_type: nil, intended_stay: nil).save(validate: false) } + + it "does not return a scheme with nil values as a duplicate" do + expect(duplicate_sets).to be_empty + end + end + + context "when there are duplicate schemes without secondary client group" do + let!(:scheme) { create(:scheme, :duplicate, owning_organisation: organisation, secondary_client_group: nil, has_other_client_group: 0) } + let!(:duplicate_scheme) { create(:scheme, :duplicate, owning_organisation: organisation, secondary_client_group: nil, has_other_client_group: 0) } + + it "does not returns the duplicates" do + expect(duplicate_sets.count).to eq(1) + expect(duplicate_sets.first).to contain_exactly(scheme.id, duplicate_scheme.id) + end + end + end end end