diff --git a/app/helpers/duplicate_logs_helper.rb b/app/helpers/duplicate_logs_helper.rb index f1efec21b..5f4e7c68a 100644 --- a/app/helpers/duplicate_logs_helper.rb +++ b/app/helpers/duplicate_logs_helper.rb @@ -27,4 +27,36 @@ module DuplicateLogsHelper first_remaining_duplicate_id = all_duplicates.map(&:id).reject { |id| id == log.id }.first send("#{log.model_name.param_key}_#{page_id}_path", log, referrer: "duplicate_logs", first_remaining_duplicate_id:, original_log_id:) end + + def duplicates_for_user(user) + duplicate_sets = { lettings: [], sales: [] } + duplicate_lettings_ids = Set.new + duplicate_sales_ids = Set.new + + user.lettings_logs(created_by: true).each do |log| + next if duplicate_lettings_ids.include? log.id + + duplicates = LettingsLog.filter_by_organisation(user.organisation).duplicate_logs(log) + next unless duplicates.any? + + duplicate_ids = [log.id, *duplicates.map(&:id)] + duplicate_sets[:lettings] << duplicate_ids + duplicate_lettings_ids << duplicate_ids + end + + user.sales_logs(created_by: true).each do |log| + next if duplicate_sales_ids.include? log.id + + duplicates = SalesLog.filter_by_organisation(user.organisation).duplicate_logs(log) + next unless duplicates.any? + + duplicate_ids = [log.id, *duplicates.map(&:id)] + duplicate_sets[:sales] << duplicate_ids + duplicate_sales_ids << duplicate_ids + end + + return if duplicate_lettings_ids.empty? && duplicate_sales_ids.empty? + + duplicate_sets + end end diff --git a/app/models/log.rb b/app/models/log.rb index dd2cc8016..e597a3bc5 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -29,6 +29,7 @@ class Log < ApplicationRecord scope :visible, -> { where(status: %w[not_started in_progress completed]) } scope :exportable, -> { where(status: %w[not_started in_progress completed deleted]) } + scope :created_by, ->(user) { where(created_by: user) } scope :filter_by_status, ->(status, _user = nil) { where status: } scope :filter_by_years, lambda { |years, _user = nil| first_year = years.shift diff --git a/app/models/user.rb b/app/models/user.rb index eccdaec47..cbaad68d3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -75,16 +75,20 @@ class User < ApplicationRecord scope :deactivated, -> { where(active: false) } scope :active_status, -> { where(active: true).where.not(last_sign_in_at: nil) } - def lettings_logs - if support? + def lettings_logs(created_by: false) + if created_by + LettingsLog.created_by(self) + elsif support? LettingsLog.all else LettingsLog.filter_by_organisation(organisation.absorbed_organisations + [organisation]) end end - def sales_logs - if support? + def sales_logs(created_by: false) + if created_by + SalesLog.created_by(self) + elsif support? SalesLog.all else SalesLog.filter_by_owning_organisation(organisation.absorbed_organisations + [organisation]) diff --git a/spec/helpers/duplicate_logs_helper_spec.rb b/spec/helpers/duplicate_logs_helper_spec.rb new file mode 100644 index 000000000..e03cae521 --- /dev/null +++ b/spec/helpers/duplicate_logs_helper_spec.rb @@ -0,0 +1,66 @@ +require "rails_helper" + +RSpec.describe DuplicateLogsHelper do + let(:org) { create(:organisation) } + let(:other_org) { create(:organisation) } + let(:current_user) { create(:user, organisation: org) } + let(:user_same_org) { create(:user, organisation: org) } + let(:user_other_org) { create(:user, organisation: other_org) } + + let(:result) { duplicates_for_user(current_user) } + + let!(:lettings_log) { create(:lettings_log, :duplicate, created_by: current_user) } + let!(:sales_log) { create(:sales_log, :duplicate, created_by: current_user) } + + context "when there are no duplicates" do + it "returns nil" do + expect(result).to be nil + end + end + + context "when there are duplicates in another org" do + before do + create(:lettings_log, :duplicate, created_by: user_other_org) + create(:sales_log, :duplicate, created_by: user_other_org) + end + + it "returns nil" do + expect(result).to be nil + end + end + + context "when another user in the same org has created a duplicate lettings log" do + let!(:duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user_same_org) } + + it "returns the ids of the duplicates in an array under the lettings key in the duplicates hash" do + expect(result).to be_a Hash + expect(result[:lettings]).to match_array [[lettings_log.id, duplicate_lettings_log.id]] + end + end + + context "when another user in the same org has created a duplicate sales log" do + let!(:duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user_same_org) } + + it "returns the ids of the duplicates in an array under the sales key in the duplicates hash" do + expect(result).to be_a Hash + expect(result[:sales]).to match_array [[sales_log.id, duplicate_sales_log.id]] + end + end + + context "when there are multiple sets of duplicates across lettings and sales" do + let!(:duplicate_lettings_log) { create(:lettings_log, :duplicate, created_by: user_same_org) } + let!(:duplicate_sales_log) { create(:sales_log, :duplicate, created_by: user_same_org) } + let!(:further_sales_log) { create(:sales_log, :duplicate, purchid: "further", created_by: current_user) } + let!(:further_duplicate_sales_logs) { create_list(:sales_log, 2, :duplicate, purchid: "further", created_by: user_same_org) } + + it "returns them all with no repeats" do + expected_sales_duplicates_result = [ + [sales_log.id, duplicate_sales_log.id], + [further_sales_log.id, *further_duplicate_sales_logs.map(&:id)], + ] + + expect(result[:lettings]).to match_array [[lettings_log.id, duplicate_lettings_log.id]] + expect(result[:sales]).to match_array expected_sales_duplicates_result + end + end +end