Browse Source

Merge branch 'main' into Fix-change-address-query-logic

pull/2998/head
Manny Dinssa 5 months ago
parent
commit
3b2302048a
  1. 2
      app/models/derived_variables/lettings_log_variables.rb
  2. 2
      app/models/form/lettings/questions/previous_let_type.rb
  3. 7
      app/models/validations/soft_validations.rb
  4. 52
      app/services/bulk_upload/sales/year2025/row_parser.rb
  5. 3
      spec/fixtures/files/lettings_log_csv_export_codes_25.csv
  6. 3
      spec/fixtures/files/lettings_log_csv_export_labels_25.csv
  7. 3
      spec/fixtures/files/lettings_log_csv_export_non_support_codes_25.csv
  8. 3
      spec/fixtures/files/lettings_log_csv_export_non_support_labels_25.csv
  9. 2
      spec/models/form/lettings/questions/previous_let_type_spec.rb
  10. 36
      spec/models/validations/soft_validations_spec.rb
  11. 48
      spec/services/bulk_upload/sales/year2025/row_parser_spec.rb
  12. 193
      spec/services/csv/lettings_log_csv_service_spec.rb

2
app/models/derived_variables/lettings_log_variables.rb

@ -18,7 +18,7 @@ module DerivedVariables::LettingsLogVariables
3 => 6, # "Rent to Buy" => "Rent to Buy basis"
4 => 7, # "London Living Rent" => "London Living Rent basis"
5 => 8, # "Other intermediate rent product" => "Another Intermediate Rent basis"
6 => 9, # "Specified accommodation - exempt accommodation, managed properties, refuges and local authority hostels" => "Specified accommodation - exempt accommodation, manged properties, refuges and local authority hostels"
6 => 9, # "Specified accommodation - exempt accommodation, managed properties, refuges and local authority hostels" => "Specified accommodation - exempt accommodation, managed properties, refuges and local authority hostels"
}.freeze
RENTTYPE_DETAIL_MAPPING = {

2
app/models/form/lettings/questions/previous_let_type.rb

@ -36,7 +36,7 @@ class Form::Lettings::Questions::PreviousLetType < ::Form::Question
"6" => { "value" => "Rent to Buy basis" },
"7" => { "value" => "London Living Rent basis" },
"8" => { "value" => "Another Intermediate Rent basis" },
"9" => { "value" => "Specified accommodation - exempt accommodation, manged properties, refuges and local authority hostels" },
"9" => { "value" => "Specified accommodation - exempt accommodation, managed properties, refuges and local authority hostels" },
"divider" => { "value" => true },
"3" => { "value" => "Don’t know" },
}.freeze

7
app/models/validations/soft_validations.rb

@ -103,13 +103,16 @@ module Validations::SoftValidations
TWO_YEARS_IN_DAYS = 730
TEN_YEARS_IN_DAYS = 3650
TWENTY_YEARS_IN_DAYS = 7300
def major_repairs_date_in_soft_range?
mrcdate.present? && startdate.present? && mrcdate.between?(startdate.to_date - TEN_YEARS_IN_DAYS, startdate.to_date - TWO_YEARS_IN_DAYS)
upper_limit = form.start_year_2025_or_later? ? TWENTY_YEARS_IN_DAYS : TEN_YEARS_IN_DAYS
mrcdate.present? && startdate.present? && mrcdate.between?(startdate.to_date - upper_limit, startdate.to_date - TWO_YEARS_IN_DAYS)
end
def voiddate_in_soft_range?
voiddate.present? && startdate.present? && voiddate.between?(startdate.to_date - TEN_YEARS_IN_DAYS, startdate.to_date - TWO_YEARS_IN_DAYS)
upper_limit = form.start_year_2025_or_later? ? TWENTY_YEARS_IN_DAYS : TEN_YEARS_IN_DAYS
voiddate.present? && startdate.present? && voiddate.between?(startdate.to_date - upper_limit, startdate.to_date - TWO_YEARS_IN_DAYS)
end
def net_income_higher_or_lower_text

52
app/services/bulk_upload/sales/year2025/row_parser.rb

@ -815,31 +815,11 @@ private
attributes["sex5"] = field_52
attributes["sex6"] = field_56
attributes["relat2"] = if field_34 == 1
"P"
else
(field_34 == 2 ? "X" : "R")
end
attributes["relat3"] = if field_42 == 1
"P"
else
(field_42 == 2 ? "X" : "R")
end
attributes["relat4"] = if field_46 == 1
"P"
else
(field_46 == 2 ? "X" : "R")
end
attributes["relat5"] = if field_50 == 1
"P"
else
(field_50 == 2 ? "X" : "R")
end
attributes["relat6"] = if field_54 == 1
"P"
else
(field_54 == 2 ? "X" : "R")
end
attributes["relat2"] = relationship_from_is_partner(field_34)
attributes["relat3"] = relationship_from_is_partner(field_42)
attributes["relat4"] = relationship_from_is_partner(field_46)
attributes["relat5"] = relationship_from_is_partner(field_50)
attributes["relat6"] = relationship_from_is_partner(field_54)
attributes["ecstat1"] = field_32
attributes["ecstat2"] = field_39
@ -1052,6 +1032,17 @@ private
field_55.present? || field_56.present? || field_54.present?
end
def relationship_from_is_partner(is_partner)
case is_partner
when 1
"P"
when 2
"X"
when 3
"R"
end
end
def details_known?(person_n)
send("person_#{person_n}_present?") ? 1 : 2
end
@ -1491,6 +1482,17 @@ private
%w[0] + GlobalConstants::COUNTRIES_ANSWER_OPTIONS.keys # 0 is "Prefers not to say"
end
def validate_relat_fields
%i[field_34 field_42 field_46 field_50 field_54].each do |field|
value = send(field)
next if value.blank?
unless (1..3).cover?(value)
errors.add(field, I18n.t("#{ERROR_BASE_KEY}.invalid_option", question: format_ending(QUESTIONS[field])))
end
end
end
def bulk_upload_organisation
Organisation.find(bulk_upload.organisation_id)
end

3
spec/fixtures/files/lettings_log_csv_export_codes_25.csv vendored

File diff suppressed because one or more lines are too long

3
spec/fixtures/files/lettings_log_csv_export_labels_25.csv vendored

File diff suppressed because one or more lines are too long

3
spec/fixtures/files/lettings_log_csv_export_non_support_codes_25.csv vendored

File diff suppressed because one or more lines are too long

3
spec/fixtures/files/lettings_log_csv_export_non_support_labels_25.csv vendored

File diff suppressed because one or more lines are too long

2
spec/models/form/lettings/questions/previous_let_type_spec.rb

@ -83,7 +83,7 @@ RSpec.describe Form::Lettings::Questions::PreviousLetType, type: :model do
"6" => { "value" => "Rent to Buy basis" },
"7" => { "value" => "London Living Rent basis" },
"8" => { "value" => "Another Intermediate Rent basis" },
"9" => { "value" => "Specified accommodation - exempt accommodation, manged properties, refuges and local authority hostels" },
"9" => { "value" => "Specified accommodation - exempt accommodation, managed properties, refuges and local authority hostels" },
"divider" => { "value" => true },
"3" => { "value" => "Don’t know" },
})

36
spec/models/validations/soft_validations_spec.rb

@ -265,6 +265,24 @@ RSpec.describe Validations::SoftValidations do
expect(record.major_repairs_date_in_soft_range?).to be false
end
end
context "with 2025 logs" do
context "when the void date is within 20 years of the tenancy start date" do
it "shows the interruption screen" do
record.startdate = Time.zone.local(2026, 2, 1)
record.mrcdate = Time.zone.local(2007, 2, 1)
expect(record.major_repairs_date_in_soft_range?).to be true
end
end
context "when the void date is less than 2 years before the tenancy start date" do
it "does not show the interruption screen" do
record.startdate = Time.zone.local(2026, 2, 1)
record.mrcdate = Time.zone.local(2025, 2, 1)
expect(record.major_repairs_date_in_soft_range?).to be false
end
end
end
end
describe "void date soft validations" do
@ -283,6 +301,24 @@ RSpec.describe Validations::SoftValidations do
expect(record.voiddate_in_soft_range?).to be false
end
end
context "with 2025 logs" do
context "when the void date is within 20 years of the tenancy start date" do
it "shows the interruption screen" do
record.startdate = Time.zone.local(2026, 2, 1)
record.voiddate = Time.zone.local(2007, 2, 1)
expect(record.voiddate_in_soft_range?).to be true
end
end
context "when the void date is less than 2 years before the tenancy start date" do
it "does not show the interruption screen" do
record.startdate = Time.zone.local(2026, 2, 1)
record.voiddate = Time.zone.local(2025, 2, 1)
expect(record.voiddate_in_soft_range?).to be false
end
end
end
end
describe "old persons shared ownership soft validations" do

48
spec/services/bulk_upload/sales/year2025/row_parser_spec.rb

@ -60,7 +60,7 @@ RSpec.describe BulkUpload::Sales::Year2025::RowParser do
field_31: "28",
field_32: "1",
field_33: "1",
field_34: "R",
field_34: "3",
field_35: "32",
field_36: "F",
field_37: "17",
@ -1145,6 +1145,52 @@ RSpec.describe BulkUpload::Sales::Year2025::RowParser do
end
end
describe "relationship field mappings" do
[
%w[field_34 relat2 2],
%w[field_42 relat3 3],
%w[field_46 relat4 4],
%w[field_50 relat5 5],
%w[field_54 relat6 6],
].each do |input_field, relationship_attribute, person_num|
describe input_field.to_s do
context "when #{input_field} is 1" do
let(:attributes) { setup_section_params.merge({ input_field.to_sym => "1", field_41: "5" }) }
it "sets relationship to P" do
expect(parser.log.public_send(relationship_attribute)).to eq("P")
end
end
context "when #{input_field} is 2" do
let(:attributes) { setup_section_params.merge({ input_field.to_sym => "2", field_41: "5" }) }
it "sets relationship to X" do
expect(parser.log.public_send(relationship_attribute)).to eq("X")
end
end
context "when #{input_field} is 3" do
let(:attributes) { setup_section_params.merge({ input_field.to_sym => "3", field_41: "5" }) }
it "sets relationship to R" do
expect(parser.log.public_send(relationship_attribute)).to eq("R")
end
end
context "when #{input_field} is 4" do
let(:attributes) { setup_section_params.merge({ input_field.to_sym => "4", field_41: "5" }) }
it "gives a validation error" do
parser.valid?
validation_message = "You must answer person #{person_num} is the partner of buyer 1."
expect(parser.errors[input_field]).to include validation_message
end
end
end
end
end
describe "field_39" do # ecstat2
context "when buyer 2 has no age but has ecstat as child" do
let(:attributes) { valid_attributes.merge({ field_35: nil, field_39: "9" }) }

193
spec/services/csv/lettings_log_csv_service_spec.rb

@ -194,6 +194,199 @@ RSpec.describe Csv::LettingsLogCsvService do
end
describe "the full CSV output" do
context "when the requested log year is 2025" do
let(:year) { 2025 }
let(:organisation) { create(:organisation, provider_type: "LA", name: "MHCLG") }
let(:log) do
create(
:lettings_log,
:ignore_validation_errors,
created_by: user,
assigned_to: user,
created_at: Time.zone.local(2025, 4, 1),
updated_at: Time.zone.local(2025, 4, 1),
owning_organisation: organisation,
managing_organisation: organisation,
needstype: 1,
renewal: 0,
startdate: Time.zone.local(2025, 4, 1),
rent_type: 1,
tenancycode: "HIJKLMN",
propcode: "ABCDEFG",
declaration: 1,
address_line1: "Address line 1",
town_or_city: "London",
postcode_full: "NW9 5LL",
la: "E09000003",
is_la_inferred: false,
address_line1_as_entered: "address line 1 as entered",
address_line2_as_entered: "address line 2 as entered",
town_or_city_as_entered: "town or city as entered",
county_as_entered: "county as entered",
postcode_full_as_entered: "AB1 2CD",
la_as_entered: "la as entered",
first_time_property_let_as_social_housing: 0,
unitletas: 2,
rsnvac: 6,
unittype_gn: 7,
builtype: 1,
wchair: 1,
beds: 3,
voiddate: Time.zone.local(2025, 3, 30),
majorrepairs: 1,
mrcdate: Time.zone.local(2025, 3, 31),
joint: 3,
startertenancy: 1,
tenancy: 4,
tenancylength: 2,
hhmemb: 4,
age1_known: 0,
age1: 35,
sex1: "F",
ethnic_group: 0,
ethnic: 2,
nationality_all: 36,
ecstat1: 0,
details_known_2: 0,
relat2: "P",
age2_known: 0,
age2: 32,
sex2: "M",
ecstat2: 6,
details_known_3: 1,
details_known_4: 0,
relat4: "R",
age4_known: 1,
sex4: "R",
ecstat4: 10,
armedforces: 1,
leftreg: 4,
reservist: 1,
preg_occ: 2,
housingneeds: 1,
housingneeds_type: 0,
housingneeds_a: 1,
housingneeds_b: 0,
housingneeds_c: 0,
housingneeds_f: 0,
housingneeds_g: 0,
housingneeds_h: 0,
housingneeds_other: 0,
illness: 1,
illness_type_1: 0,
illness_type_2: 1,
illness_type_3: 0,
illness_type_4: 0,
illness_type_5: 0,
illness_type_6: 0,
illness_type_7: 0,
illness_type_8: 0,
illness_type_9: 0,
illness_type_10: 0,
layear: 2,
waityear: 7,
reason: 4,
prevten: 6,
homeless: 1,
ppcodenk: 1,
ppostcode_full: "TN23 6LZ",
previous_la_known: 1,
prevloc: "E07000105",
reasonpref: 1,
rp_homeless: 0,
rp_insan_unsat: 1,
rp_medwel: 0,
rp_hardship: 0,
rp_dontknow: 0,
cbl: 0,
chr: 1,
cap: 0,
accessible_register: 0,
referral: 2,
net_income_known: 0,
incref: 0,
incfreq: 1,
earnings: 268,
hb: 6,
has_benefits: 1,
benefits: 1,
period: 2,
brent: 200,
scharge: 50,
pscharge: 40,
supcharg: 35,
tcharge: 325,
hbrentshortfall: 1,
tshortfall_known: 1,
tshortfall: 12,
)
end
context "when exporting with human readable labels" do
let(:export_type) { "labels" }
context "when the current user is a support user" do
let(:user) { create(:user, :support, organisation:, email: "s.port@jeemayle.com") }
it "exports the CSV with 2025 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_25.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = attribute_line.index(attribute)
content_line[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current user is not a support user" do
let(:user) { create(:user, :data_provider, organisation:, email: "choreographer@owtluk.com") }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels_25.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = attribute_line.index(attribute)
content_line[index] = nil
end
expect(csv).to eq expected_content
end
end
end
context "when exporting values as codes" do
let(:export_type) { "codes" }
context "when the current user is a support user" do
let(:user) { create(:user, :support, organisation:, email: "s.port@jeemayle.com") }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes_25.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = attribute_line.index(attribute)
content_line[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the current user is not a support user" do
let(:user) { create(:user, :data_provider, organisation:, email: "choreographer@owtluk.com") }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes_25.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = attribute_line.index(attribute)
content_line[index] = nil
end
expect(csv).to eq expected_content
end
end
end
end
context "when the requested log year is 2024" do
let(:year) { 2024 }
let(:organisation) { create(:organisation, provider_type: "LA", name: "MHCLG") }

Loading…
Cancel
Save