From eb620ed91d6c3480988737117bd90f6b92c104d2 Mon Sep 17 00:00:00 2001 From: Kat Date: Thu, 11 Jan 2024 13:25:25 +0000 Subject: [PATCH] Update existing duplicate log references --- lib/tasks/set_duplicate_references.rake | 27 ++ .../tasks/set_duplicate_references_spec.rb | 284 ++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 lib/tasks/set_duplicate_references.rake create mode 100644 spec/lib/tasks/set_duplicate_references_spec.rb diff --git a/lib/tasks/set_duplicate_references.rake b/lib/tasks/set_duplicate_references.rake new file mode 100644 index 000000000..98b5a11ce --- /dev/null +++ b/lib/tasks/set_duplicate_references.rake @@ -0,0 +1,27 @@ +desc "Set duplicate references for sales and lettings logs" +task set_duplicate_references: :environment do + SalesLog.filter_by_year(2023).duplicate_sets.each do |duplicate_set| + duplicate_log_reference_id = generate_new_duplicate_log_reference_id + next if duplicate_set.any? { |log_id| DuplicateLogReference.exists?(log_id:, log_type: "SalesLog") } + + duplicate_set.each do |log_id| + DuplicateLogReference.create(log_id:, log_type: "SalesLog", duplicate_log_reference_id:) + end + end + + LettingsLog.filter_by_year(2023).duplicate_sets.each do |duplicate_set| + duplicate_log_reference_id = generate_new_duplicate_log_reference_id + next if duplicate_set.any? { |log_id| DuplicateLogReference.exists?(log_id:, log_type: "LettingsLog") } + + duplicate_set.each do |log_id| + DuplicateLogReference.create(log_id:, log_type: "LettingsLog", duplicate_log_reference_id:) + end + end +end + +def generate_new_duplicate_log_reference_id + loop do + duplicate_log_reference_id = SecureRandom.random_number(1_000_000) + return duplicate_log_reference_id unless DuplicateLogReference.exists?(duplicate_log_reference_id:) + end +end diff --git a/spec/lib/tasks/set_duplicate_references_spec.rb b/spec/lib/tasks/set_duplicate_references_spec.rb new file mode 100644 index 000000000..05dce0018 --- /dev/null +++ b/spec/lib/tasks/set_duplicate_references_spec.rb @@ -0,0 +1,284 @@ +require "rails_helper" +require "rake" + +RSpec.describe "set_duplicate_references" do + describe ":set_duplicate_references", type: :task do + subject(:task) { Rake::Task["set_duplicate_references"] } + + before do + Rake.application.rake_require("tasks/set_duplicate_references") + Rake::Task.define_task(:environment) + task.reenable + end + + context "when the rake task is run" do + context "and there are sales duplicates in 1 organisation" do + let(:user) { create(:user) } + let!(:sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:second_duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:sales_log_without_duplicates) { create(:sales_log, created_by: user) } + + it "creates duplicate references for sales logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(sales_log.duplicates.count).to eq(0) + expect(sales_log.duplicate_log_references).to be_empty + expect(duplicate_sales_log.duplicates.count).to eq(0) + expect(duplicate_sales_log.duplicate_log_references).to be_empty + expect(second_duplicate_sales_log.duplicates.count).to eq(0) + expect(second_duplicate_sales_log.duplicate_log_references).to be_empty + expect(sales_log_without_duplicates.duplicates.count).to eq(0) + expect(sales_log_without_duplicates.duplicate_log_references).to be_empty + + task.invoke + sales_log.reload + duplicate_sales_log.reload + second_duplicate_sales_log.reload + sales_log_without_duplicates.reload + + expect(DuplicateLogReference.count).to eq(3) + expect(sales_log.duplicates.count).to eq(2) + expect(sales_log.duplicate_log_references.count).to eq(1) + expect(duplicate_sales_log.duplicates.count).to eq(2) + expect(duplicate_sales_log.duplicate_log_references.count).to eq(1) + expect(second_duplicate_sales_log.duplicates.count).to eq(2) + expect(second_duplicate_sales_log.duplicate_log_references.count).to eq(1) + expect(sales_log_without_duplicates.duplicates.count).to eq(0) + expect(sales_log_without_duplicates.duplicate_log_references).to be_empty + expect(sales_log.duplicate_log_references.count).to eq(1) + expect(sales_log.duplicate_log_reference_id).to eq(duplicate_sales_log.duplicate_log_reference_id) + expect(sales_log.duplicate_log_reference_id).to eq(second_duplicate_sales_log.duplicate_log_reference_id) + end + + it "does not create the references twice" do + expect(DuplicateLogReference.count).to eq(0) + + task.invoke + + expect(DuplicateLogReference.count).to eq(3) + + task.reenable + task.invoke + + expect(DuplicateLogReference.count).to eq(3) + end + end + + context "and there are sales duplicates in multiple organisations" do + let(:user) { create(:user) } + let!(:sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:sales_log_without_duplicates) { create(:sales_log, created_by: user) } + let(:other_user) { create(:user) } + let!(:other_sales_log) { create(:sales_log, :duplicate, created_by: other_user) } + let!(:other_duplicate_sales_log) { create(:sales_log, :duplicate, created_by: other_user) } + let!(:other_sales_log_without_duplicates) { create(:sales_log, created_by: other_user) } + + it "creates separate duplicate references for sales logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(sales_log.duplicates.count).to eq(0) + expect(sales_log.duplicate_log_references).to be_empty + expect(duplicate_sales_log.duplicates.count).to eq(0) + expect(duplicate_sales_log.duplicate_log_references).to be_empty + expect(sales_log_without_duplicates.duplicates.count).to eq(0) + expect(sales_log_without_duplicates.duplicate_log_references).to be_empty + + expect(other_sales_log.duplicates.count).to eq(0) + expect(other_sales_log.duplicate_log_references).to be_empty + expect(other_duplicate_sales_log.duplicates.count).to eq(0) + expect(other_duplicate_sales_log.duplicate_log_references).to be_empty + expect(other_sales_log_without_duplicates.duplicates.count).to eq(0) + expect(other_sales_log_without_duplicates.duplicate_log_references).to be_empty + + task.invoke + sales_log.reload + duplicate_sales_log.reload + sales_log_without_duplicates.reload + + expect(DuplicateLogReference.count).to eq(4) + expect(sales_log.duplicates.count).to eq(1) + expect(sales_log.duplicate_log_references.count).to eq(1) + expect(duplicate_sales_log.duplicates.count).to eq(1) + expect(duplicate_sales_log.duplicate_log_references.count).to eq(1) + expect(sales_log_without_duplicates.duplicates.count).to eq(0) + expect(sales_log_without_duplicates.duplicate_log_references).to be_empty + expect(sales_log.duplicate_log_reference_id).to eq(duplicate_sales_log.duplicate_log_reference_id) + + expect(other_sales_log.duplicates.count).to eq(1) + expect(other_sales_log.duplicate_log_references.count).to eq(1) + expect(other_duplicate_sales_log.duplicates.count).to eq(1) + expect(other_duplicate_sales_log.duplicate_log_references.count).to eq(1) + expect(other_sales_log_without_duplicates.duplicates.count).to eq(0) + expect(other_sales_log_without_duplicates.duplicate_log_references).to be_empty + expect(other_sales_log.duplicate_log_reference_id).to eq(other_duplicate_sales_log.duplicate_log_reference_id) + expect(other_sales_log.duplicate_log_reference_id).not_to eq(sales_log.duplicate_log_reference_id) + end + end + + context "and there are sales duplicates for non 2023/24 collection period" do + let(:user) { create(:user) } + let!(:sales_log) { create(:sales_log, :duplicate, created_by: user) } + let!(:duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user) } + + before do + sales_log.saledate = Time.zone.local(2022, 4, 4) + sales_log.save!(validate: false) + duplicate_sales_log.saledate = Time.zone.local(2022, 4, 4) + duplicate_sales_log.save!(validate: false) + end + + it "does not create duplicate references for sales logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(sales_log.duplicates.count).to eq(0) + expect(sales_log.duplicate_log_references).to be_empty + expect(duplicate_sales_log.duplicates.count).to eq(0) + expect(duplicate_sales_log.duplicate_log_references).to be_empty + + task.invoke + sales_log.reload + duplicate_sales_log.reload + + expect(DuplicateLogReference.count).to eq(0) + expect(sales_log.duplicates.count).to eq(0) + expect(sales_log.duplicate_log_references).to be_empty + expect(duplicate_sales_log.duplicates.count).to eq(0) + expect(duplicate_sales_log.duplicate_log_references).to be_empty + end + end + + context "and there are lettings duplicates in 1 organisation" do + let(:user) { create(:user) } + let!(:lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:second_duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:lettings_log_without_duplicates) { create(:lettings_log, created_by: user) } + + it "creates duplicate references for lettings logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(lettings_log.duplicates.count).to eq(0) + expect(lettings_log.duplicate_log_references).to be_empty + expect(duplicate_lettings_log.duplicates.count).to eq(0) + expect(duplicate_lettings_log.duplicate_log_references).to be_empty + expect(second_duplicate_lettings_log.duplicates.count).to eq(0) + expect(second_duplicate_lettings_log.duplicate_log_references).to be_empty + expect(lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(lettings_log_without_duplicates.duplicate_log_references).to be_empty + + task.invoke + lettings_log.reload + duplicate_lettings_log.reload + second_duplicate_lettings_log.reload + lettings_log_without_duplicates.reload + + expect(DuplicateLogReference.count).to eq(3) + expect(lettings_log.duplicates.count).to eq(2) + expect(lettings_log.duplicate_log_references.count).to eq(1) + expect(duplicate_lettings_log.duplicates.count).to eq(2) + expect(duplicate_lettings_log.duplicate_log_references.count).to eq(1) + expect(second_duplicate_lettings_log.duplicates.count).to eq(2) + expect(second_duplicate_lettings_log.duplicate_log_references.count).to eq(1) + expect(lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(lettings_log_without_duplicates.duplicate_log_references).to be_empty + expect(lettings_log.duplicate_log_references.count).to eq(1) + expect(lettings_log.duplicate_log_reference_id).to eq(duplicate_lettings_log.duplicate_log_reference_id) + expect(lettings_log.duplicate_log_reference_id).to eq(second_duplicate_lettings_log.duplicate_log_reference_id) + end + + it "does not create the references twice" do + expect(DuplicateLogReference.count).to eq(0) + + task.invoke + + expect(DuplicateLogReference.count).to eq(3) + + task.reenable + task.invoke + + expect(DuplicateLogReference.count).to eq(3) + end + end + + context "and there are lettings duplicates in multiple organisations" do + let(:user) { create(:user) } + let!(:lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:lettings_log_without_duplicates) { create(:lettings_log, created_by: user) } + let(:other_user) { create(:user) } + let!(:other_lettings_log) { create(:lettings_log, :duplicate, created_by: other_user) } + let!(:other_duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: other_user) } + let!(:other_lettings_log_without_duplicates) { create(:lettings_log, created_by: other_user) } + + it "creates separate duplicate references for lettings logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(lettings_log.duplicates.count).to eq(0) + expect(lettings_log.duplicate_log_references).to be_empty + expect(duplicate_lettings_log.duplicates.count).to eq(0) + expect(duplicate_lettings_log.duplicate_log_references).to be_empty + expect(lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(lettings_log_without_duplicates.duplicate_log_references).to be_empty + + expect(other_lettings_log.duplicates.count).to eq(0) + expect(other_lettings_log.duplicate_log_references).to be_empty + expect(other_duplicate_lettings_log.duplicates.count).to eq(0) + expect(other_duplicate_lettings_log.duplicate_log_references).to be_empty + expect(other_lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(other_lettings_log_without_duplicates.duplicate_log_references).to be_empty + + task.invoke + lettings_log.reload + duplicate_lettings_log.reload + lettings_log_without_duplicates.reload + + expect(DuplicateLogReference.count).to eq(4) + expect(lettings_log.duplicates.count).to eq(1) + expect(lettings_log.duplicate_log_references.count).to eq(1) + expect(duplicate_lettings_log.duplicates.count).to eq(1) + expect(duplicate_lettings_log.duplicate_log_references.count).to eq(1) + expect(lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(lettings_log_without_duplicates.duplicate_log_references).to be_empty + expect(lettings_log.duplicate_log_reference_id).to eq(duplicate_lettings_log.duplicate_log_reference_id) + + expect(other_lettings_log.duplicates.count).to eq(1) + expect(other_lettings_log.duplicate_log_references.count).to eq(1) + expect(other_duplicate_lettings_log.duplicates.count).to eq(1) + expect(other_duplicate_lettings_log.duplicate_log_references.count).to eq(1) + expect(other_lettings_log_without_duplicates.duplicates.count).to eq(0) + expect(other_lettings_log_without_duplicates.duplicate_log_references).to be_empty + expect(other_lettings_log.duplicate_log_reference_id).to eq(other_duplicate_lettings_log.duplicate_log_reference_id) + expect(other_lettings_log.duplicate_log_reference_id).not_to eq(lettings_log.duplicate_log_reference_id) + end + end + + context "and there are lettings duplicates for non 2023/24 collection period" do + let(:user) { create(:user) } + let!(:lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + let!(:duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user) } + + before do + lettings_log.startdate = Time.zone.local(2022, 4, 4) + lettings_log.save!(validate: false) + duplicate_lettings_log.startdate = Time.zone.local(2022, 4, 4) + duplicate_lettings_log.save!(validate: false) + end + + it "does not create duplicate references for lettings logs" do + expect(DuplicateLogReference.count).to eq(0) + expect(lettings_log.duplicates.count).to eq(0) + expect(lettings_log.duplicate_log_references).to be_empty + expect(duplicate_lettings_log.duplicates.count).to eq(0) + expect(duplicate_lettings_log.duplicate_log_references).to be_empty + + task.invoke + lettings_log.reload + duplicate_lettings_log.reload + + expect(DuplicateLogReference.count).to eq(0) + expect(lettings_log.duplicates.count).to eq(0) + expect(lettings_log.duplicate_log_references).to be_empty + expect(duplicate_lettings_log.duplicates.count).to eq(0) + expect(duplicate_lettings_log.duplicate_log_references).to be_empty + end + end + end + end +end