Browse Source

CLDC-4119: Update main site duplicate logs check

adds sexrab1 to the duplicate log attributes

needs special care for the location and uprn attributes
CLDC-4119-amend-lettings-duplicate-log-check
Samuel Young 5 days ago
parent
commit
cd96d9556d
  1. 78
      app/models/lettings_log.rb
  2. 6
      lib/tasks/handle_unpended_logs.rake

78
app/models/lettings_log.rb

@ -21,6 +21,7 @@ class LettingsLog < Log
include Validations::DateValidations include Validations::DateValidations
include Validations::FinancialValidations include Validations::FinancialValidations
include MoneyFormattingHelper include MoneyFormattingHelper
include CollectionTimeHelper
has_paper_trail has_paper_trail
@ -41,6 +42,8 @@ class LettingsLog < Log
belongs_to :managing_organisation, class_name: "Organisation", optional: true belongs_to :managing_organisation, class_name: "Organisation", optional: true
scope :filter_by_year, ->(year) { where(startdate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) } scope :filter_by_year, ->(year) { where(startdate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) }
scope :filter_by_year_or_later, ->(year) { where("lettings_logs.startdate >= ?", Time.zone.local(year.to_i, 4, 1)) }
scope :filter_by_year_or_earlier, ->(year) { where("lettings_logs.startdate < ?", Time.zone.local(year.to_i + 1, 4, 1)) }
scope :filter_by_years_or_nil, lambda { |years, _user = nil| scope :filter_by_years_or_nil, lambda { |years, _user = nil|
first_year = years.shift first_year = years.shift
query = filter_by_year(first_year) query = filter_by_year(first_year)
@ -85,9 +88,15 @@ class LettingsLog < Log
scope :age1_answered, -> { where.not(age1: nil).or(where(age1_known: 1)) } scope :age1_answered, -> { where.not(age1: nil).or(where(age1_known: 1)) }
scope :tcharge_answered, -> { where.not(tcharge: nil).or(where(household_charge: 1)).or(where(is_carehome: 1)) } scope :tcharge_answered, -> { where.not(tcharge: nil).or(where(household_charge: 1)).or(where(is_carehome: 1)) }
scope :chcharge_answered, -> { where.not(chcharge: nil).or(where(is_carehome: [nil, 0])) } scope :chcharge_answered, -> { where.not(chcharge: nil).or(where(is_carehome: [nil, 0])) }
scope :location_for_log_answered, ->(log) { where(location_id: log.location_id).or(where(needstype: 1)) } # once 2025 logs are removed this logic can be simplified
scope :postcode_for_log_answered, ->(log) { where(postcode_full: log.postcode_full).or(where(needstype: 2)) } # pre 2025, match on location if supported, or address if general needs
scope :location_answered, -> { where.not(location_id: nil).or(where(needstype: 1)) } # post 2026, match on address only
scope :location_for_log_answered_as, ->(log) { where(location_id: log.location_id).or(where(needstype: 1)).or(filter_by_year_or_later(2026)) }
scope :address_for_log_answered_as, lambda { |log|
where(postcode_full: log.postcode_full).where(address_line1: log.address_line1).where(uprn: log.uprn)
.or(filter_by_year_or_earlier(2025).where(needstype: 2))
}
scope :location_answered, -> { where.not(location_id: nil).or(where(needstype: 1)).or(filter_by_year_or_later(2026)) }
scope :postcode_answered, -> { where.not(postcode_full: nil).or(where(needstype: 2)) } scope :postcode_answered, -> { where.not(postcode_full: nil).or(where(needstype: 2)) }
scope :duplicate_logs, lambda { |log| scope :duplicate_logs, lambda { |log|
visible visible
@ -99,26 +108,27 @@ class LettingsLog < Log
.age1_answered .age1_answered
.tcharge_answered .tcharge_answered
.chcharge_answered .chcharge_answered
.location_for_log_answered(log) .location_for_log_answered_as(log)
.postcode_for_log_answered(log) .address_for_log_answered_as(log)
.where(log.slice(*DUPLICATE_LOG_ATTRIBUTES)) .where(log.slice(*DUPLICATE_LOG_ATTRIBUTES))
} }
scope :duplicate_sets, lambda { |assigned_to_id = nil| scope :duplicate_sets_2025_and_earlier, lambda { |assigned_to_id = nil|
scope = visible scope = visible
.group(*DUPLICATE_LOG_ATTRIBUTES, :postcode_full, :location_id) .filter_by_year_or_earlier(2025)
.where.not(startdate: nil) .group(*DUPLICATE_LOG_ATTRIBUTES, :postcode_full, :location_id, :uprn, :address_line1)
.where.not(sex1: nil) .where.not(startdate: nil)
.where.not(ecstat1: nil) .where.not(sex1: nil)
.where.not(needstype: nil) .where.not(ecstat1: nil)
.age1_answered .where.not(needstype: nil)
.tcharge_answered .age1_answered
.chcharge_answered .tcharge_answered
.location_answered .chcharge_answered
.postcode_answered .location_answered
.having( .postcode_answered
"COUNT(*) > 1", .having(
) "COUNT(*) > 1",
)
if assigned_to_id if assigned_to_id
scope = scope.having("MAX(CASE WHEN assigned_to_id = ? THEN 1 ELSE 0 END) >= 1", assigned_to_id) scope = scope.having("MAX(CASE WHEN assigned_to_id = ? THEN 1 ELSE 0 END) >= 1", assigned_to_id)
@ -126,6 +136,34 @@ class LettingsLog < Log
scope.pluck("ARRAY_AGG(id)") scope.pluck("ARRAY_AGG(id)")
} }
scope :duplicate_sets_2026_and_later, lambda { |assigned_to_id = nil|
scope = visible
.filter_by_year_or_later(2026)
# separate function as location needs to be fully ignored in 2026
.group(*DUPLICATE_LOG_ATTRIBUTES, :postcode_full, :uprn, :address_line1)
.where.not(startdate: nil)
.where.not(sex1: nil)
.where.not(ecstat1: nil)
.where.not(needstype: nil)
.age1_answered
.tcharge_answered
.chcharge_answered
.location_answered
.postcode_answered
.having(
"COUNT(*) > 1",
)
if assigned_to_id
scope = scope.having("MAX(CASE WHEN assigned_to_id = ? THEN 1 ELSE 0 END) >= 1", assigned_to_id)
end
scope.pluck("ARRAY_AGG(id)")
}
scope :duplicate_sets, lambda { |assigned_to_id = nil|
duplicate_sets_2025_and_earlier(assigned_to_id) + duplicate_sets_2026_and_later(assigned_to_id)
}
scope :with_illness_without_type, lambda { scope :with_illness_without_type, lambda {
where(illness: 1, where(illness: 1,
illness_type_1: false, illness_type_1: false,
@ -150,7 +188,7 @@ class LettingsLog < Log
HAS_BENEFITS_OPTIONS = [1, 6, 8, 7].freeze HAS_BENEFITS_OPTIONS = [1, 6, 8, 7].freeze
NUM_OF_WEEKS_FROM_PERIOD = { 2 => 26, 3 => 13, 4 => 12, 5 => 50, 6 => 49, 7 => 48, 8 => 47, 9 => 46, 11 => 51, 1 => 52, 10 => 53 }.freeze NUM_OF_WEEKS_FROM_PERIOD = { 2 => 26, 3 => 13, 4 => 12, 5 => 50, 6 => 49, 7 => 48, 8 => 47, 9 => 46, 11 => 51, 1 => 52, 10 => 53 }.freeze
SUFFIX_FROM_PERIOD = { 2 => "every 2 weeks", 3 => "every 4 weeks", 4 => "every month" }.freeze SUFFIX_FROM_PERIOD = { 2 => "every 2 weeks", 3 => "every 4 weeks", 4 => "every month" }.freeze
DUPLICATE_LOG_ATTRIBUTES = %w[owning_organisation_id tenancycode startdate age1_known age1 sex1 ecstat1 tcharge household_charge chcharge].freeze DUPLICATE_LOG_ATTRIBUTES = %w[owning_organisation_id tenancycode startdate age1_known age1 sex1 sexrab1 ecstat1 tcharge household_charge chcharge].freeze
RENT_TYPE = { RENT_TYPE = {
social_rent: 0, social_rent: 0,
affordable_rent: 1, affordable_rent: 1,

6
lib/tasks/handle_unpended_logs.rake

@ -6,7 +6,7 @@ task :handle_unpended_logs, %i[perform_updates] => :environment do |_task, args|
query = "SELECT \"versions\".* FROM \"versions\" WHERE \"versions\".\"item_type\" = 'LettingsLog' AND whodunnit is null AND ((object_changes like '%status:\n- 3\n- 1%') OR (object_changes like '%status:\n- 3\n- 2%'))" query = "SELECT \"versions\".* FROM \"versions\" WHERE \"versions\".\"item_type\" = 'LettingsLog' AND whodunnit is null AND ((object_changes like '%status:\n- 3\n- 1%') OR (object_changes like '%status:\n- 3\n- 2%'))"
results = pg.execute(query) results = pg.execute(query)
duplicate_log_attributes = %w[owning_organisation_id tenancycode startdate age1_known age1 sex1 ecstat1 tcharge household_charge chcharge] duplicate_log_attributes = %w[owning_organisation_id tenancycode startdate age1_known age1 sex1 sexrab1 ecstat1 tcharge household_charge chcharge]
seen = [].to_set seen = [].to_set
@ -47,8 +47,8 @@ task :handle_unpended_logs, %i[perform_updates] => :environment do |_task, args|
.age1_answered .age1_answered
.tcharge_answered .tcharge_answered
.chcharge_answered .chcharge_answered
.location_for_log_answered(log) .location_for_log_answered_as(log)
.postcode_for_log_answered(log) .address_for_log_answered_as(log)
.where(log.slice(*duplicate_log_attributes)) .where(log.slice(*duplicate_log_attributes))
duplicate_count = duplicates.length duplicate_count = duplicates.length

Loading…
Cancel
Save