diff --git a/spec/features/lettings_log_spec.rb b/spec/features/lettings_log_spec.rb
index 483924f0f..b8ff6885a 100644
--- a/spec/features/lettings_log_spec.rb
+++ b/spec/features/lettings_log_spec.rb
@@ -94,6 +94,32 @@ RSpec.describe "Lettings Log Features" do
end
end
+ context "when visiting a subsection check answers page" do
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :about_completed) }
+
+ it "has the correct breadcrumbs with the correct links" do
+ visit lettings_log_setup_check_answers_path(lettings_log)
+ breadcrumbs = page.find_all(".govuk-breadcrumbs__link")
+ expect(breadcrumbs.first.text).to eq "Logs"
+ expect(breadcrumbs.first[:href]).to eq lettings_logs_path
+ expect(breadcrumbs[1].text).to eq "Log #{lettings_log.id}"
+ expect(breadcrumbs[1][:href]).to eq lettings_log_path(lettings_log)
+ end
+ end
+
+ context "when reviewing a complete log" do
+ let(:lettings_log) { FactoryBot.create(:lettings_log, :completed) }
+
+ it "has the correct breadcrumbs with the correct links" do
+ visit review_lettings_log_path(lettings_log)
+ breadcrumbs = page.find_all(".govuk-breadcrumbs__link")
+ expect(breadcrumbs.first.text).to eq "Logs"
+ expect(breadcrumbs.first[:href]).to eq lettings_logs_path
+ expect(breadcrumbs[1].text).to eq "Log #{lettings_log.id}"
+ expect(breadcrumbs[1][:href]).to eq lettings_log_path(lettings_log)
+ end
+ end
+
context "when the owning organisation question isn't answered" do
it "doesn't show the managing agent question" do
visit("/lettings-logs")
diff --git a/spec/features/sales_log_spec.rb b/spec/features/sales_log_spec.rb
index 04331d824..759b298f3 100644
--- a/spec/features/sales_log_spec.rb
+++ b/spec/features/sales_log_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe "Sales Log Features" do
click_link("Logs")
end
- it "navigates you to the lettings logs page" do
+ it "navigates you to the sales logs page" do
expect(page).to have_current_path("/sales-logs")
end
end
@@ -65,4 +65,48 @@ RSpec.describe "Sales Log Features" do
end
end
end
+
+ context "when signed in as a support user" do
+ let(:devise_notify_mailer) { DeviseNotifyMailer.new }
+ let(:notify_client) { instance_double(Notifications::Client) }
+ let(:otp) { "999111" }
+ let(:organisation) { FactoryBot.create(:organisation, name: "Big ORG") }
+ let(:user) { FactoryBot.create(:user, :support, last_sign_in_at: Time.zone.now, organisation:) }
+ let(:sales_log) { FactoryBot.create(:sales_log, :completed) }
+
+ before do
+ allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
+ allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
+ allow(notify_client).to receive(:send_email).and_return(true)
+ allow(SecureRandom).to receive(:random_number).and_return(otp)
+ visit("/sales-logs")
+ fill_in("user[email]", with: user.email)
+ fill_in("user[password]", with: user.password)
+ click_button("Sign in")
+ fill_in("code", with: otp)
+ click_button("Submit")
+ end
+
+ context "when visiting a subsection check answers page as a support user" do
+ it "has the correct breadcrumbs with the correct links" do
+ visit sales_log_setup_check_answers_path(sales_log.id)
+ breadcrumbs = page.find_all(".govuk-breadcrumbs__link")
+ expect(breadcrumbs.first.text).to eq "Logs"
+ expect(breadcrumbs.first[:href]).to eq sales_logs_path
+ expect(breadcrumbs[1].text).to eq "Log #{sales_log.id}"
+ expect(breadcrumbs[1][:href]).to eq sales_log_path(sales_log.id)
+ end
+ end
+
+ context "when reviewing a complete log" do
+ it "has the correct breadcrumbs with the correct links" do
+ visit review_sales_log_path(sales_log.id, sales_log: true)
+ breadcrumbs = page.find_all(".govuk-breadcrumbs__link")
+ expect(breadcrumbs.first.text).to eq "Logs"
+ expect(breadcrumbs.first[:href]).to eq sales_logs_path
+ expect(breadcrumbs[1].text).to eq "Log #{sales_log.id}"
+ expect(breadcrumbs[1][:href]).to eq sales_log_path(sales_log.id)
+ end
+ end
+ end
end
From f3e7d2c62b5010d05f98332d1ccef7c2a8649ae7 Mon Sep 17 00:00:00 2001
From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com>
Date: Tue, 21 Mar 2023 13:30:14 +0000
Subject: [PATCH 07/31] CLDC-2073 app crashing if needs type is changed (#1368)
* add some methods on lettings log and use them and already existing methods to make depends on human readbale for pages in property information subsection
* reformat answer options for neatness
* ensure that property information subsection is conditionally not shown under correct conditions
* amend method to find the path for the next question to answer so that if no questions in the next section are currently routed to, it goes to the section after that
* make amendments for failing test and linting
* remove unnecessary method
* remove unnecessary conditions from depends on, the displayed in tasklist method override is sufficient
* test the change to the method creating a link to the next subsection
* minor refactor to displayed_is_tasklist condition and changes in testing
* implement the fix on 22/23 form also
* write a test covering the fix
* removal not_renewal? method and tweak depends on for all pages using that method
* linty fluff begone
* correct some errors in tests after changes to factories
* minor testing amendments after rebase
---
app/models/form.rb | 4 +--
...rst_time_property_let_as_social_housing.rb | 2 +-
.../lettings/pages/new_build_handover_date.rb | 6 +---
.../lettings/pages/property_building_type.rb | 2 +-
.../form/lettings/pages/property_let_type.rb | 2 +-
.../pages/property_local_authority.rb | 2 +-
.../lettings/pages/property_major_repairs.rb | 13 +-------
.../pages/property_number_of_bedrooms.rb | 2 +-
...ty_number_of_times_relet_not_social_let.rb | 2 +-
...operty_number_of_times_relet_social_let.rb | 2 +-
.../form/lettings/pages/property_postcode.rb | 2 +-
.../form/lettings/pages/property_unit_type.rb | 2 +-
.../property_vacancy_reason_first_let.rb | 2 +-
.../property_vacancy_reason_not_first_let.rb | 2 +-
.../pages/property_wheelchair_accessible.rb | 2 +-
.../lettings/pages/void_or_renewal_date.rb | 13 +-------
.../lettings/questions/rsnvac_first_let.rb | 9 ++----
.../subsections/property_information.rb | 4 +++
app/models/form/subsection.rb | 11 +++++--
app/models/lettings_log.rb | 4 +++
config/forms/2022_2023.json | 10 +++++-
spec/factories/lettings_log.rb | 6 ++--
spec/fixtures/exports/general_needs_log.csv | 2 +-
spec/fixtures/exports/general_needs_log.xml | 4 +--
.../exports/supported_housing_logs.xml | 4 +--
.../property_wheelchair_accessible_spec.rb | 4 +--
.../subsections/property_information_spec.rb | 10 ++----
spec/models/form_spec.rb | 20 ++++++++++++
.../requests/lettings_logs_controller_spec.rb | 32 +++++++++++++++++++
29 files changed, 110 insertions(+), 70 deletions(-)
diff --git a/app/models/form.rb b/app/models/form.rb
index c7bb4f2b0..9fa908427 100644
--- a/app/models/form.rb
+++ b/app/models/form.rb
@@ -111,8 +111,8 @@ class Form
when :in_progress
"#{next_subsection.id}/check_answers".dasherize
when :not_started
- first_question_in_subsection = next_subsection.pages.find { |page| page.routed_to?(log, nil) }.id
- first_question_in_subsection.to_s.dasherize
+ first_question_in_subsection = next_subsection.pages.find { |page| page.routed_to?(log, nil) }
+ first_question_in_subsection ? first_question_in_subsection.id.to_s.dasherize : next_incomplete_section_redirect_path(next_subsection, log)
else
"error"
end
diff --git a/app/models/form/lettings/pages/first_time_property_let_as_social_housing.rb b/app/models/form/lettings/pages/first_time_property_let_as_social_housing.rb
index fc65488e2..eafb145b5 100644
--- a/app/models/form/lettings/pages/first_time_property_let_as_social_housing.rb
+++ b/app/models/form/lettings/pages/first_time_property_let_as_social_housing.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::FirstTimePropertyLetAsSocialHousing < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "first_time_property_let_as_social_housing"
- @depends_on = [{ "renewal" => 0 }]
+ @depends_on = [{ "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/new_build_handover_date.rb b/app/models/form/lettings/pages/new_build_handover_date.rb
index 7b13c7727..e7cb2e5d9 100644
--- a/app/models/form/lettings/pages/new_build_handover_date.rb
+++ b/app/models/form/lettings/pages/new_build_handover_date.rb
@@ -2,11 +2,7 @@ class Form::Lettings::Pages::NewBuildHandoverDate < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "new_build_handover_date"
- @depends_on = [
- { "renewal" => 0, "rsnvac" => 15 },
- { "renewal" => 0, "rsnvac" => 16 },
- { "renewal" => 0, "rsnvac" => 17 },
- ]
+ @depends_on = [{ "is_renewal?" => false, "has_first_let_vacancy_reason?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_building_type.rb b/app/models/form/lettings/pages/property_building_type.rb
index aec9fa4a9..ff3d76e0b 100644
--- a/app/models/form/lettings/pages/property_building_type.rb
+++ b/app/models/form/lettings/pages/property_building_type.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyBuildingType < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_building_type"
- @depends_on = [{ "needstype" => 1 }]
+ @depends_on = [{ "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_let_type.rb b/app/models/form/lettings/pages/property_let_type.rb
index 3f9011c99..6bdb94803 100644
--- a/app/models/form/lettings/pages/property_let_type.rb
+++ b/app/models/form/lettings/pages/property_let_type.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyLetType < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_let_type"
- @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "renewal" => 0 }]
+ @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_local_authority.rb b/app/models/form/lettings/pages/property_local_authority.rb
index 711d908d8..2c64e3628 100644
--- a/app/models/form/lettings/pages/property_local_authority.rb
+++ b/app/models/form/lettings/pages/property_local_authority.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyLocalAuthority < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_local_authority"
- @depends_on = [{ "is_la_inferred" => false, "needstype" => 1 }]
+ @depends_on = [{ "is_la_inferred" => false, "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_major_repairs.rb b/app/models/form/lettings/pages/property_major_repairs.rb
index 54a32a1ad..985b5dce1 100644
--- a/app/models/form/lettings/pages/property_major_repairs.rb
+++ b/app/models/form/lettings/pages/property_major_repairs.rb
@@ -2,18 +2,7 @@ class Form::Lettings::Pages::PropertyMajorRepairs < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_major_repairs"
- @depends_on = [
- { "renewal" => 0, "rsnvac" => 5 },
- { "renewal" => 0, "rsnvac" => 6 },
- { "renewal" => 0, "rsnvac" => 8 },
- { "renewal" => 0, "rsnvac" => 9 },
- { "renewal" => 0, "rsnvac" => 10 },
- { "renewal" => 0, "rsnvac" => 11 },
- { "renewal" => 0, "rsnvac" => 12 },
- { "renewal" => 0, "rsnvac" => 13 },
- { "renewal" => 0, "rsnvac" => 18 },
- { "renewal" => 0, "rsnvac" => 19 },
- ]
+ @depends_on = [{ "is_renewal?" => false, "vacancy_reason_not_renewal_or_first_let?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_number_of_bedrooms.rb b/app/models/form/lettings/pages/property_number_of_bedrooms.rb
index 89c056e00..c3a1a2365 100644
--- a/app/models/form/lettings/pages/property_number_of_bedrooms.rb
+++ b/app/models/form/lettings/pages/property_number_of_bedrooms.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyNumberOfBedrooms < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_number_of_bedrooms"
- @depends_on = [{ "needstype" => 1 }]
+ @depends_on = [{ "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_number_of_times_relet_not_social_let.rb b/app/models/form/lettings/pages/property_number_of_times_relet_not_social_let.rb
index 6061fcaaa..b82a4757e 100644
--- a/app/models/form/lettings/pages/property_number_of_times_relet_not_social_let.rb
+++ b/app/models/form/lettings/pages/property_number_of_times_relet_not_social_let.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyNumberOfTimesReletNotSocialLet < ::Form::Pa
def initialize(id, hsh, subsection)
super
@id = "property_number_of_times_relet_not_social_let"
- @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "renewal" => 0 }]
+ @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_number_of_times_relet_social_let.rb b/app/models/form/lettings/pages/property_number_of_times_relet_social_let.rb
index f1a136249..5785a2961 100644
--- a/app/models/form/lettings/pages/property_number_of_times_relet_social_let.rb
+++ b/app/models/form/lettings/pages/property_number_of_times_relet_social_let.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyNumberOfTimesReletSocialLet < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_number_of_times_relet_social_let"
- @depends_on = [{ "first_time_property_let_as_social_housing" => 1, "renewal" => 0 }]
+ @depends_on = [{ "first_time_property_let_as_social_housing" => 1, "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_postcode.rb b/app/models/form/lettings/pages/property_postcode.rb
index 720cd3106..a40d4140f 100644
--- a/app/models/form/lettings/pages/property_postcode.rb
+++ b/app/models/form/lettings/pages/property_postcode.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyPostcode < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_postcode"
- @depends_on = [{ "needstype" => 1 }]
+ @depends_on = [{ "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_unit_type.rb b/app/models/form/lettings/pages/property_unit_type.rb
index 6db4db4e4..727e740cd 100644
--- a/app/models/form/lettings/pages/property_unit_type.rb
+++ b/app/models/form/lettings/pages/property_unit_type.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyUnitType < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_unit_type"
- @depends_on = [{ "needstype" => 1 }]
+ @depends_on = [{ "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_vacancy_reason_first_let.rb b/app/models/form/lettings/pages/property_vacancy_reason_first_let.rb
index 3a14827de..85dd5d690 100644
--- a/app/models/form/lettings/pages/property_vacancy_reason_first_let.rb
+++ b/app/models/form/lettings/pages/property_vacancy_reason_first_let.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyVacancyReasonFirstLet < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_vacancy_reason_first_let"
- @depends_on = [{ "first_time_property_let_as_social_housing" => 1, "renewal" => 0 }]
+ @depends_on = [{ "first_time_property_let_as_social_housing" => 1, "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_vacancy_reason_not_first_let.rb b/app/models/form/lettings/pages/property_vacancy_reason_not_first_let.rb
index 1b2c147ed..4fdf7fef5 100644
--- a/app/models/form/lettings/pages/property_vacancy_reason_not_first_let.rb
+++ b/app/models/form/lettings/pages/property_vacancy_reason_not_first_let.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyVacancyReasonNotFirstLet < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_vacancy_reason_not_first_let"
- @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "renewal" => 0 }]
+ @depends_on = [{ "first_time_property_let_as_social_housing" => 0, "is_renewal?" => false }]
end
def questions
diff --git a/app/models/form/lettings/pages/property_wheelchair_accessible.rb b/app/models/form/lettings/pages/property_wheelchair_accessible.rb
index e5d673ef0..3b2b226b6 100644
--- a/app/models/form/lettings/pages/property_wheelchair_accessible.rb
+++ b/app/models/form/lettings/pages/property_wheelchair_accessible.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::PropertyWheelchairAccessible < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_wheelchair_accessible"
- @depends_on = [{ "is_supported_housing?" => false }]
+ @depends_on = [{ "is_general_needs?" => true }]
end
def questions
diff --git a/app/models/form/lettings/pages/void_or_renewal_date.rb b/app/models/form/lettings/pages/void_or_renewal_date.rb
index 1ea4ea982..0905f1058 100644
--- a/app/models/form/lettings/pages/void_or_renewal_date.rb
+++ b/app/models/form/lettings/pages/void_or_renewal_date.rb
@@ -2,18 +2,7 @@ class Form::Lettings::Pages::VoidOrRenewalDate < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "void_or_renewal_date"
- @depends_on = [
- { "renewal" => 0, "rsnvac" => 5 },
- { "renewal" => 0, "rsnvac" => 6 },
- { "renewal" => 0, "rsnvac" => 8 },
- { "renewal" => 0, "rsnvac" => 9 },
- { "renewal" => 0, "rsnvac" => 10 },
- { "renewal" => 0, "rsnvac" => 11 },
- { "renewal" => 0, "rsnvac" => 12 },
- { "renewal" => 0, "rsnvac" => 13 },
- { "renewal" => 0, "rsnvac" => 18 },
- { "renewal" => 0, "rsnvac" => 19 },
- ]
+ @depends_on = [{ "is_renewal?" => false, "vacancy_reason_not_renewal_or_first_let?" => true }]
end
def questions
diff --git a/app/models/form/lettings/questions/rsnvac_first_let.rb b/app/models/form/lettings/questions/rsnvac_first_let.rb
index 8d7da0433..df66b57cd 100644
--- a/app/models/form/lettings/questions/rsnvac_first_let.rb
+++ b/app/models/form/lettings/questions/rsnvac_first_let.rb
@@ -12,11 +12,8 @@ class Form::Lettings::Questions::RsnvacFirstLet < ::Form::Question
end
ANSWER_OPTIONS = {
- "16" =>
- { "value" => "First let of conversion, rehabilitation or acquired property" },
- "17" =>
- { "value" => "First let of leased property" },
- "15" =>
- { "value" => "First let of new-build property" },
+ "16" => { "value" => "First let of conversion, rehabilitation or acquired property" },
+ "17" => { "value" => "First let of leased property" },
+ "15" => { "value" => "First let of new-build property" },
}.freeze
end
diff --git a/app/models/form/lettings/subsections/property_information.rb b/app/models/form/lettings/subsections/property_information.rb
index cc07535ae..6e20ea7cf 100644
--- a/app/models/form/lettings/subsections/property_information.rb
+++ b/app/models/form/lettings/subsections/property_information.rb
@@ -27,4 +27,8 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
Form::Lettings::Pages::PropertyMajorRepairsValueCheck.new(nil, nil, self),
].compact
end
+
+ def displayed_in_tasklist?(log)
+ !(log.is_supported_housing? && log.is_renewal?)
+ end
end
diff --git a/app/models/form/subsection.rb b/app/models/form/subsection.rb
index 3f5827c92..f38ecc327 100644
--- a/app/models/form/subsection.rb
+++ b/app/models/form/subsection.rb
@@ -7,6 +7,7 @@ class Form::Subsection
if hsh
@label = hsh["label"]
@depends_on = hsh["depends_on"]
+ @displayed_in_tasklist_from_json = hsh["displayed_in_tasklist"]
@pages = hsh["pages"].map { |s_id, p| Form::Page.new(s_id, p, self) }
end
end
@@ -48,7 +49,13 @@ class Form::Subsection
end
end
- def displayed_in_tasklist?(_log)
- true
+ def displayed_in_tasklist?(log)
+ return true unless @displayed_in_tasklist_from_json
+
+ @displayed_in_tasklist_from_json.any? do |conditions|
+ conditions.all? do |method, expected_return_value|
+ log.send(method) == expected_return_value
+ end
+ end
end
end
diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb
index 4524ead12..36d81a537 100644
--- a/app/models/lettings_log.rb
+++ b/app/models/lettings_log.rb
@@ -287,6 +287,10 @@ class LettingsLog < Log
[15, 16, 17].include?(rsnvac)
end
+ def vacancy_reason_not_renewal_or_first_let?
+ [5, 6, 8, 9, 10, 11, 12, 13, 18, 19].include? rsnvac
+ end
+
def previous_tenancy_was_temporary?
# 4: Tied housing or renting with job
# 6: Supported housing
diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json
index bd88b1335..7cee2b737 100644
--- a/config/forms/2022_2023.json
+++ b/config/forms/2022_2023.json
@@ -939,7 +939,15 @@
}
}
}
- }
+ },
+ "displayed_in_tasklist": [
+ {
+ "is_supported_housing?": false
+ },
+ {
+ "is_renewal?": false
+ }
+ ]
},
"tenancy_information": {
"label": "Tenancy information",
diff --git a/spec/factories/lettings_log.rb b/spec/factories/lettings_log.rb
index b0667b817..994b69c33 100644
--- a/spec/factories/lettings_log.rb
+++ b/spec/factories/lettings_log.rb
@@ -30,7 +30,7 @@ FactoryBot.define do
age1 { 34 }
sex1 { "M" }
ethnic { 2 }
- national { 4 }
+ national { 18 }
ecstat1 { 2 }
hhmemb { 1 }
end
@@ -43,7 +43,7 @@ FactoryBot.define do
sex1 { "F" }
ethnic_group { 0 }
ethnic { 2 }
- national { 4 }
+ national { 13 }
prevten { 6 }
ecstat1 { 0 }
hhmemb { 2 }
@@ -79,7 +79,7 @@ FactoryBot.define do
supcharg { 35 }
tcharge { 325 }
layear { 2 }
- waityear { 1 }
+ waityear { 7 }
postcode_known { 1 }
postcode_full { Faker::Address.postcode }
reasonpref { 1 }
diff --git a/spec/fixtures/exports/general_needs_log.csv b/spec/fixtures/exports/general_needs_log.csv
index 0185f54e0..37ee27089 100644
--- a/spec/fixtures/exports/general_needs_log.csv
+++ b/spec/fixtures/exports/general_needs_log.csv
@@ -1,2 +1,2 @@
status,tenancycode,age1,sex1,ethnic,national,prevten,ecstat1,hhmemb,age2,sex2,ecstat2,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,leftreg,reservist,illness,preg_occ,startertenancy,tenancylength,tenancy,ppostcode_full,rsnvac,unittype_gn,beds,offered,wchair,earnings,incfreq,benefits,period,layear,waityear,postcode_full,reasonpref,cbl,chr,cap,reasonother,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,illness_type_1,illness_type_2,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,irproduct_other,reason,propcode,la,prevloc,hb,hbrentshortfall,mrcdate,incref,startdate,armedforces,unitletas,builtype,voiddate,renttype,needstype,lettype,totchild,totelder,totadult,nocharge,referral,brent,scharge,pscharge,supcharg,tcharge,tshortfall,chcharge,ppcodenk,has_benefits,renewal,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat2,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,hhtype,new_old,vacdays,formid,owningorgid,owningorgname,hcnum,maningorgid,maningorgname,manhcnum,createddate,uploaddate
-2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,4,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,1,NW1 5TY,1,2,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-05-01T00:00:00+01:00,2022-05-01T00:00:00+01:00
+2,BZ737,35,F,2,13,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,4,1,1,1,2,1,5,1,SE2 6RT,6,7,3,2,1,68,1,1,2,2,7,NW1 5TY,1,2,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05T10:36:49+01:00,0,2022-02-02T10:36:49+00:00,1,2,1,2019-11-03T00:00:00+00:00,2,1,7,0,0,2,0,2,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-05-01T00:00:00+01:00,2022-05-01T00:00:00+01:00
diff --git a/spec/fixtures/exports/general_needs_log.xml b/spec/fixtures/exports/general_needs_log.xml
index f05de09e3..11c50ed4e 100644
--- a/spec/fixtures/exports/general_needs_log.xml
+++ b/spec/fixtures/exports/general_needs_log.xml
@@ -6,7 +6,7 @@
35
F
2
-
4
+
13
6
0
2
@@ -51,7 +51,7 @@
1
2
2
-
1
+
7
NW1 5TY
1
2
diff --git a/spec/fixtures/exports/supported_housing_logs.xml b/spec/fixtures/exports/supported_housing_logs.xml
index 0a0ed0981..3b535c226 100644
--- a/spec/fixtures/exports/supported_housing_logs.xml
+++ b/spec/fixtures/exports/supported_housing_logs.xml
@@ -6,7 +6,7 @@
35
F
2
-
4
+
13
6
0
2
@@ -50,7 +50,7 @@
1
2
2
-
1
+
7
SW1A 2AA
1
2
diff --git a/spec/models/form/lettings/pages/property_wheelchair_accessible_spec.rb b/spec/models/form/lettings/pages/property_wheelchair_accessible_spec.rb
index 4e487e239..b96a55feb 100644
--- a/spec/models/form/lettings/pages/property_wheelchair_accessible_spec.rb
+++ b/spec/models/form/lettings/pages/property_wheelchair_accessible_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Form::Lettings::Pages::PropertyWheelchairAccessible, type: :model
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
- expect(page.subsection).to eq(subsection)
+ expect(page.subsection).to be(subsection)
end
it "has correct questions" do
@@ -26,6 +26,6 @@ RSpec.describe Form::Lettings::Pages::PropertyWheelchairAccessible, type: :model
end
it "has the correct depends_on" do
- expect(page.depends_on).to eq([{ "is_supported_housing?" => false }])
+ expect(page.depends_on).to eq([{ "is_general_needs?" => true }])
end
end
diff --git a/spec/models/form/lettings/subsections/property_information_spec.rb b/spec/models/form/lettings/subsections/property_information_spec.rb
index 227773487..8b30964c3 100644
--- a/spec/models/form/lettings/subsections/property_information_spec.rb
+++ b/spec/models/form/lettings/subsections/property_information_spec.rb
@@ -1,10 +1,8 @@
require "rails_helper"
RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
- subject(:property_information) { described_class.new(subsection_id, subsection_definition, section) }
+ subject(:property_information) { described_class.new(nil, nil, section) }
- let(:subsection_id) { nil }
- let(:subsection_definition) { nil }
let(:section) { instance_double(Form::Lettings::Sections::TenancyAndProperty) }
it "has correct section" do
@@ -44,10 +42,6 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
end
it "has the correct depends_on" do
- expect(property_information.depends_on).to eq([
- {
- "non_location_setup_questions_completed?" => true,
- },
- ])
+ expect(property_information.depends_on).to eq([{ "non_location_setup_questions_completed?" => true }])
end
end
diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb
index 57995d90b..3236623c1 100644
--- a/spec/models/form_spec.rb
+++ b/spec/models/form_spec.rb
@@ -183,6 +183,26 @@ RSpec.describe Form, type: :model do
expect(form.next_incomplete_section_redirect_path(subsection, lettings_log)).to eq("declaration")
end
end
+
+ context "when no pages or questions in the next subsection are routed to" do
+ let(:subsection) { form.get_subsection("setup") }
+
+ around do |example|
+ FormHandler.instance.use_real_forms!
+
+ example.run
+
+ FormHandler.instance.use_fake_forms!
+ end
+
+ it "finds the path to the section after" do
+ lettings_log.startdate = Time.zone.local(2022, 9, 1)
+ lettings_log.renewal = 1
+ lettings_log.needstype = 2
+ lettings_log.postcode_known = 0
+ expect(form.next_incomplete_section_redirect_path(subsection, lettings_log)).to eq("joint")
+ end
+ end
end
describe "invalidated_page_questions" do
diff --git a/spec/requests/lettings_logs_controller_spec.rb b/spec/requests/lettings_logs_controller_spec.rb
index 066cd1f35..b8e7f0f78 100644
--- a/spec/requests/lettings_logs_controller_spec.rb
+++ b/spec/requests/lettings_logs_controller_spec.rb
@@ -891,6 +891,38 @@ RSpec.describe LettingsLogsController, type: :request do
end
end
+ context "when a lettings log is for a renewal of supported housing, so property information does not need to show" do
+ let(:lettings_log) do
+ FactoryBot.create(
+ :lettings_log,
+ owning_organisation: user.organisation,
+ managing_organisation: user.organisation,
+ created_by: user,
+ startdate: Time.zone.now,
+ renewal: 1,
+ needstype: 2,
+ rent_type: 3,
+ postcode_known: 0,
+ )
+ end
+
+ before do
+ sign_in user
+ end
+
+ around do |example|
+ FormHandler.instance.use_real_forms!
+ example.run
+ FormHandler.instance.use_fake_forms!
+ end
+
+ it "does not crash the app if postcode_known is not nil" do
+ expect {
+ get "/lettings-logs/#{lettings_log.id}", headers:, params: {}
+ }.not_to raise_error(ActionView::Template::Error)
+ end
+ end
+
context "with a lettings log with a single section complete" do
let(:section_completed_lettings_log) do
FactoryBot.create(
From 1acd3b3aafe81f7289f0009567245759a4630aac Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Tue, 21 Mar 2023 14:18:58 +0000
Subject: [PATCH 08/31] CLDC-2074 Change care home charges validation (#1410)
* Add carehome charges value check field
* Add carehome charges soft validation to 23/24 forms
* Update care_home_charge_expected_not_provided?
* Add care_home_charges_value_check to 22/23
* Update csv
* Add care_home_charges_value_check to 21/22 form
* Update import to set value_chech to yes
---
.../pages/care_home_charges_value_check.rb | 15 +++++
.../care_home_charges_value_check.rb | 14 +++++
.../subsections/income_and_benefits.rb | 1 +
app/models/lettings_log.rb | 6 +-
.../imports/lettings_logs_import_service.rb | 3 +-
config/forms/2021_2022.json | 36 ++++++++++++
config/forms/2022_2023.json | 36 ++++++++++++
config/locales/en.yml | 2 +
...124749_add_carehome_charges_value_check.rb | 5 ++
db/schema.rb | 1 +
.../fixtures/files/lettings_logs_download.csv | 4 +-
.../lettings_logs_download_codes_only.csv | 4 +-
.../lettings_logs_download_non_support.csv | 4 +-
.../care_home_charges_value_check_spec.rb | 44 +++++++++++++++
.../care_home_charges_value_check_spec.rb | 56 +++++++++++++++++++
.../subsections/income_and_benefits_spec.rb | 1 +
spec/models/lettings_log_spec.rb | 2 +
.../validations/soft_validations_spec.rb | 34 +++++++++++
.../csv/lettings_log_csv_service_spec.rb | 1 +
.../lettings_logs_import_service_spec.rb | 21 +++++++
20 files changed, 282 insertions(+), 8 deletions(-)
create mode 100644 app/models/form/lettings/pages/care_home_charges_value_check.rb
create mode 100644 app/models/form/lettings/questions/care_home_charges_value_check.rb
create mode 100644 db/migrate/20230313124749_add_carehome_charges_value_check.rb
create mode 100644 spec/models/form/lettings/pages/care_home_charges_value_check_spec.rb
create mode 100644 spec/models/form/lettings/questions/care_home_charges_value_check_spec.rb
diff --git a/app/models/form/lettings/pages/care_home_charges_value_check.rb b/app/models/form/lettings/pages/care_home_charges_value_check.rb
new file mode 100644
index 000000000..32468e364
--- /dev/null
+++ b/app/models/form/lettings/pages/care_home_charges_value_check.rb
@@ -0,0 +1,15 @@
+class Form::Lettings::Pages::CareHomeChargesValueCheck < ::Form::Page
+ def initialize(id, hsh, subsection)
+ super
+ @id = "care_home_charges_value_check"
+ @depends_on = [{ "care_home_charge_expected_not_provided?" => true }]
+ @title_text = {
+ "translation" => "soft_validations.care_home_charges.title_text",
+ }
+ @informative_text = ""
+ end
+
+ def questions
+ @questions ||= [Form::Lettings::Questions::CareHomeChargesValueCheck.new(nil, nil, self)]
+ end
+end
diff --git a/app/models/form/lettings/questions/care_home_charges_value_check.rb b/app/models/form/lettings/questions/care_home_charges_value_check.rb
new file mode 100644
index 000000000..fdb5aabbd
--- /dev/null
+++ b/app/models/form/lettings/questions/care_home_charges_value_check.rb
@@ -0,0 +1,14 @@
+class Form::Lettings::Questions::CareHomeChargesValueCheck < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "carehome_charges_value_check"
+ @check_answer_label = "Care home charges confirmation"
+ @header = "Are you sure there are no care home charges?"
+ @type = "interruption_screen"
+ @check_answers_card_number = 0
+ @answer_options = ANSWER_OPTIONS
+ @hidden_in_check_answers = { "depends_on" => [{ "carehome_charges_value_check" => 0 }, { "carehome_charges_value_check" => 1 }] }
+ end
+
+ ANSWER_OPTIONS = { "0" => { "value" => "Yes" }, "1" => { "value" => "No" } }.freeze
+end
diff --git a/app/models/form/lettings/subsections/income_and_benefits.rb b/app/models/form/lettings/subsections/income_and_benefits.rb
index 92adf3c5e..30ba3a7e0 100644
--- a/app/models/form/lettings/subsections/income_and_benefits.rb
+++ b/app/models/form/lettings/subsections/income_and_benefits.rb
@@ -19,6 +19,7 @@ class Form::Lettings::Subsections::IncomeAndBenefits < ::Form::Subsection
Form::Lettings::Pages::CareHomeBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::CareHome4Weekly.new(nil, nil, self),
Form::Lettings::Pages::CareHomeMonthly.new(nil, nil, self),
+ Form::Lettings::Pages::CareHomeChargesValueCheck.new(nil, nil, self),
Form::Lettings::Pages::RentWeekly.new(nil, nil, self),
Form::Lettings::Pages::RentBiWeekly.new(nil, nil, self),
Form::Lettings::Pages::Rent4Weekly.new(nil, nil, self),
diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb
index 36d81a537..f8c817c56 100644
--- a/app/models/lettings_log.rb
+++ b/app/models/lettings_log.rb
@@ -53,7 +53,7 @@ class LettingsLog < Log
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org).or(where(managing_organisation: org)) }
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze
- OPTIONAL_FIELDS = %w[first_time_property_let_as_social_housing tenancycode propcode].freeze
+ OPTIONAL_FIELDS = %w[first_time_property_let_as_social_housing tenancycode propcode chcharge].freeze
RENT_TYPE_MAPPING_LABELS = { 1 => "Social Rent", 2 => "Affordable Rent", 3 => "Intermediate Rent" }.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, 1 => 52 }.freeze
@@ -505,6 +505,10 @@ class LettingsLog < Log
update!(created_by: nil)
end
+ def care_home_charge_expected_not_provided?
+ is_carehome == 1 && chcharge.blank?
+ end
+
private
def reset_derived_questions
diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb
index 34582091d..9e5de20ba 100644
--- a/app/services/imports/lettings_logs_import_service.rb
+++ b/app/services/imports/lettings_logs_import_service.rb
@@ -235,6 +235,7 @@ module Imports
attributes["retirement_value_check"] = 0
attributes["rent_value_check"] = 0
attributes["net_income_value_check"] = 0
+ attributes["carehome_charges_value_check"] = 0
# Sets the log creator
owner_id = meta_field_value(xml_doc, "owner-user-id").strip
@@ -339,7 +340,7 @@ module Imports
end
def fields_not_present_in_softwire_data
- %w[majorrepairs illness_type_0 tshortfall_known pregnancy_value_check retirement_value_check rent_value_check net_income_value_check major_repairs_date_value_check void_date_value_check housingneeds_type housingneeds_other created_by]
+ %w[majorrepairs illness_type_0 tshortfall_known pregnancy_value_check retirement_value_check rent_value_check net_income_value_check major_repairs_date_value_check void_date_value_check carehome_charges_value_check housingneeds_type housingneeds_other created_by]
end
def check_status_completed(lettings_log, previous_status)
diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json
index d4e01cfd1..dfcf83fb6 100644
--- a/config/forms/2021_2022.json
+++ b/config/forms/2021_2022.json
@@ -7812,6 +7812,42 @@
}
]
},
+ "care_home_charges_value_check": {
+ "depends_on": [
+ {
+ "care_home_charge_expected_not_provided?": true
+ }
+ ],
+ "title_text": {
+ "translation": "soft_validations.care_home_charges.title_text"
+ },
+ "informative_text": {},
+ "questions": {
+ "carehome_charges_value_check": {
+ "check_answer_label": "Care home charges confirmation",
+ "hidden_in_check_answers": {
+ "depends_on": [
+ {
+ "carehome_charges_value_check": 0
+ },
+ {
+ "carehome_charges_value_check": 1
+ }
+ ]
+ },
+ "header": "Are you sure there are no care home charges?",
+ "type": "interruption_screen",
+ "answer_options": {
+ "0": {
+ "value": "Yes"
+ },
+ "1": {
+ "value": "No"
+ }
+ }
+ }
+ }
+ },
"rent_weekly": {
"header": "Household rent and charges",
"description": "",
diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json
index 7cee2b737..6a1b8cc40 100644
--- a/config/forms/2022_2023.json
+++ b/config/forms/2022_2023.json
@@ -7782,6 +7782,42 @@
}
]
},
+ "care_home_charges_value_check": {
+ "depends_on": [
+ {
+ "care_home_charge_expected_not_provided?": true
+ }
+ ],
+ "title_text": {
+ "translation": "soft_validations.care_home_charges.title_text"
+ },
+ "informative_text": {},
+ "questions": {
+ "carehome_charges_value_check": {
+ "check_answer_label": "Care home charges confirmation",
+ "hidden_in_check_answers": {
+ "depends_on": [
+ {
+ "carehome_charges_value_check": 0
+ },
+ {
+ "carehome_charges_value_check": 1
+ }
+ ]
+ },
+ "header": "Are you sure there are no care home charges?",
+ "type": "interruption_screen",
+ "answer_options": {
+ "0": {
+ "value": "Yes"
+ },
+ "1": {
+ "value": "No"
+ }
+ }
+ }
+ }
+ },
"rent_weekly": {
"header": "Household rent and charges",
"description": "",
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 053929f46..36d8b93f8 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -528,6 +528,8 @@ en:
discounted_sale_value:
title_text: "Mortgage, deposit, and grant total must equal £%{value_with_discount}"
informative_text: "Your given mortgage, deposit and grant total is £%{mortgage_deposit_and_grant_total}"
+ care_home_charges:
+ title_text: "Care home charges should be provided if this is a care home accommodation"
devise:
two_factor_authentication:
diff --git a/db/migrate/20230313124749_add_carehome_charges_value_check.rb b/db/migrate/20230313124749_add_carehome_charges_value_check.rb
new file mode 100644
index 000000000..5ba9e64ea
--- /dev/null
+++ b/db/migrate/20230313124749_add_carehome_charges_value_check.rb
@@ -0,0 +1,5 @@
+class AddCarehomeChargesValueCheck < ActiveRecord::Migration[7.0]
+ def change
+ add_column :lettings_logs, :carehome_charges_value_check, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 2cffbaf9f..92b0d9a63 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -286,6 +286,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_20_084057) do
t.string "address_line2"
t.string "town_or_city"
t.string "county"
+ t.integer "carehome_charges_value_check"
t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
t.index ["location_id"], name: "index_lettings_logs_on_location_id"
diff --git a/spec/fixtures/files/lettings_logs_download.csv b/spec/fixtures/files/lettings_logs_download.csv
index 394c3b920..463f81d3c 100644
--- a/spec/fixtures/files/lettings_logs_download.csv
+++ b/spec/fixtures/files/lettings_logs_download.csv
@@ -1,2 +1,2 @@
-id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
-{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
+id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,carehome_charges_value_check,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
+{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
diff --git a/spec/fixtures/files/lettings_logs_download_codes_only.csv b/spec/fixtures/files/lettings_logs_download_codes_only.csv
index 423675c5b..6d15538ef 100644
--- a/spec/fixtures/files/lettings_logs_download_codes_only.csv
+++ b/spec/fixtures/files/lettings_logs_download_codes_only.csv
@@ -1,2 +1,2 @@
-id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
-{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,false,DLUHC,DLUHC,2021,2,,2 October 2021,2,,,,,,,,,,,,,,,,,,,,false,,,,,false,Westminster,E09000033,,SE1 1TE,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},0,1,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,6,A,Westminster,{location_startdate}
+id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,carehome_charges_value_check,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
+{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,false,DLUHC,DLUHC,2021,2,,2 October 2021,2,,,,,,,,,,,,,,,,,,,,false,,,,,false,Westminster,E09000033,,SE1 1TE,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},0,1,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,6,A,Westminster,{location_startdate}
diff --git a/spec/fixtures/files/lettings_logs_download_non_support.csv b/spec/fixtures/files/lettings_logs_download_non_support.csv
index a2fa80f4f..cc89d6bfb 100644
--- a/spec/fixtures/files/lettings_logs_download_non_support.csv
+++ b/spec/fixtures/files/lettings_logs_download_non_support.csv
@@ -1,2 +1,2 @@
-id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
-{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
+id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,uprn,uprn_known,uprn_confirmed,address_line1,address_line2,town_or_city,county,carehome_charges_value_check,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
+{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
diff --git a/spec/models/form/lettings/pages/care_home_charges_value_check_spec.rb b/spec/models/form/lettings/pages/care_home_charges_value_check_spec.rb
new file mode 100644
index 000000000..c81538146
--- /dev/null
+++ b/spec/models/form/lettings/pages/care_home_charges_value_check_spec.rb
@@ -0,0 +1,44 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::CareHomeChargesValueCheck, type: :model do
+ subject(:page) { described_class.new(nil, page_definition, subsection) }
+
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has the correct header" do
+ expect(page.header).to be nil
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be nil
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(%w[carehome_charges_value_check])
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("care_home_charges_value_check")
+ end
+
+ it "has correct depends_on" do
+ expect(page.depends_on).to eq(
+ [{ "care_home_charge_expected_not_provided?" => true }],
+ )
+ end
+
+ it "has the correct title_text" do
+ expect(page.title_text).to eq({
+ "translation" => "soft_validations.care_home_charges.title_text",
+ })
+ end
+
+ it "has the correct informative_text" do
+ expect(page.informative_text).to eq("")
+ end
+end
diff --git a/spec/models/form/lettings/questions/care_home_charges_value_check_spec.rb b/spec/models/form/lettings/questions/care_home_charges_value_check_spec.rb
new file mode 100644
index 000000000..d31891c5d
--- /dev/null
+++ b/spec/models/form/lettings/questions/care_home_charges_value_check_spec.rb
@@ -0,0 +1,56 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::CareHomeChargesValueCheck, type: :model do
+ subject(:question) { described_class.new(nil, question_definition, page) }
+
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("carehome_charges_value_check")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Are you sure there are no care home charges?")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to eq("Care home charges confirmation")
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("interruption_screen")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct answer_options" do
+ expect(question.answer_options).to eq({
+ "0" => { "value" => "Yes" },
+ "1" => { "value" => "No" },
+ })
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers).to eq({
+ "depends_on" => [
+ {
+ "carehome_charges_value_check" => 0,
+ },
+ {
+ "carehome_charges_value_check" => 1,
+ },
+ ],
+ })
+ end
+end
diff --git a/spec/models/form/lettings/subsections/income_and_benefits_spec.rb b/spec/models/form/lettings/subsections/income_and_benefits_spec.rb
index 2c4310d5b..8dd4f88a3 100644
--- a/spec/models/form/lettings/subsections/income_and_benefits_spec.rb
+++ b/spec/models/form/lettings/subsections/income_and_benefits_spec.rb
@@ -25,6 +25,7 @@ RSpec.describe Form::Lettings::Subsections::IncomeAndBenefits, type: :model do
care_home_bi_weekly
care_home_4_weekly
care_home_monthly
+ care_home_charges_value_check
rent_weekly
rent_bi_weekly
rent_4_weekly
diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb
index 57b5de21a..43cbc69ce 100644
--- a/spec/models/lettings_log_spec.rb
+++ b/spec/models/lettings_log_spec.rb
@@ -2235,6 +2235,7 @@ RSpec.describe LettingsLog do
first_time_property_let_as_social_housing
tenancycode
propcode
+ chcharge
tenancylength
])
end
@@ -2248,6 +2249,7 @@ RSpec.describe LettingsLog do
first_time_property_let_as_social_housing
tenancycode
propcode
+ chcharge
tenancylength
address_line2
county
diff --git a/spec/models/validations/soft_validations_spec.rb b/spec/models/validations/soft_validations_spec.rb
index 3ce2b4527..b71d91a62 100644
--- a/spec/models/validations/soft_validations_spec.rb
+++ b/spec/models/validations/soft_validations_spec.rb
@@ -327,4 +327,38 @@ RSpec.describe Validations::SoftValidations do
end
end
end
+
+ describe "#care_home_charge_expected_not_provided?" do
+ it "returns false if is_carehome is 'No'" do
+ record.period = 3
+ record.is_carehome = 0
+ record.chcharge = nil
+
+ expect(record).not_to be_care_home_charge_expected_not_provided
+ end
+
+ it "returns false if is_carehome is not given" do
+ record.period = 3
+ record.is_carehome = nil
+ record.chcharge = nil
+
+ expect(record).not_to be_care_home_charge_expected_not_provided
+ end
+
+ it "returns false if chcharge is given" do
+ record.period = 3
+ record.is_carehome = 1
+ record.chcharge = 40
+
+ expect(record).not_to be_care_home_charge_expected_not_provided
+ end
+
+ it "returns true if is_carehome is 'Yes' and chcharge is not given" do
+ record.period = 3
+ record.is_carehome = 1
+ record.chcharge = nil
+
+ expect(record).to be_care_home_charge_expected_not_provided
+ end
+ end
end
diff --git a/spec/services/csv/lettings_log_csv_service_spec.rb b/spec/services/csv/lettings_log_csv_service_spec.rb
index b1064acd5..141bae6fb 100644
--- a/spec/services/csv/lettings_log_csv_service_spec.rb
+++ b/spec/services/csv/lettings_log_csv_service_spec.rb
@@ -155,6 +155,7 @@ RSpec.describe Csv::LettingsLogCsvService do
period
is_carehome
chcharge
+ carehome_charges_value_check
brent
scharge
pscharge
diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb
index bfd907620..5b56efdfb 100644
--- a/spec/services/imports/lettings_logs_import_service_spec.rb
+++ b/spec/services/imports/lettings_logs_import_service_spec.rb
@@ -416,6 +416,27 @@ RSpec.describe Imports::LettingsLogsImportService do
end
end
+ context "and the carehome charge soft validation is triggered (carehome_charge_value_check)" do
+ let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
+
+ before do
+ scheme2.update!(registered_under_care_act: 2)
+ lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id
+ lettings_log_xml.at_xpath("//xmlns:Q18b").content = ""
+ lettings_log_xml.at_xpath("//xmlns:Q18ai").content = ""
+ lettings_log_xml.at_xpath("//xmlns:Q18aii").content = ""
+ lettings_log_xml.at_xpath("//xmlns:Q18aiii").content = ""
+ lettings_log_xml.at_xpath("//xmlns:Q18aiv").content = ""
+ lettings_log_xml.at_xpath("//xmlns:Q18av").content = ""
+ end
+
+ it "completes the log" do
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+ expect(lettings_log.status).to eq("completed")
+ end
+ end
+
context "and this is a supported housing log with multiple locations under a scheme" do
let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
From aad771b3841ad57cf1ab6af3c614f22605c830a3 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Tue, 21 Mar 2023 15:51:26 +0000
Subject: [PATCH 09/31] CLDC-2143 Set more default fields and don't clear setup
values (#1450)
* Set default hhregresstill
* Don't clear type if it errors
* Make mortgagelender mandatory and add a don't know option
* Infer mortgagelender as don't know by default
---
.../form/sales/questions/mortgage_lender.rb | 47 +++++++++++++
app/models/sales_log.rb | 2 +-
.../imports/sales_logs_import_service.rb | 8 ++-
.../sales/questions/mortgage_lender_spec.rb | 47 +++++++++++++
spec/models/sales_log_spec.rb | 2 -
.../imports/sales_logs_import_service_spec.rb | 69 +++++++++++++++++++
6 files changed, 170 insertions(+), 5 deletions(-)
diff --git a/app/models/form/sales/questions/mortgage_lender.rb b/app/models/form/sales/questions/mortgage_lender.rb
index 1fee10b8b..ad584aab5 100644
--- a/app/models/form/sales/questions/mortgage_lender.rb
+++ b/app/models/form/sales/questions/mortgage_lender.rb
@@ -56,8 +56,55 @@ class Form::Sales::Questions::MortgageLender < ::Form::Question
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
+ "0" => "Don’t know",
}.freeze
+ def displayed_answer_options(_log, _user = nil)
+ {
+ "" => "Select an option",
+ "1" => "Atom Bank",
+ "2" => "Barclays Bank PLC",
+ "3" => "Bath Building Society",
+ "4" => "Buckinghamshire Building Society",
+ "5" => "Cambridge Building Society",
+ "6" => "Coventry Building Society",
+ "7" => "Cumberland Building Society",
+ "8" => "Darlington Building Society",
+ "9" => "Dudley Building Society",
+ "10" => "Ecology Building Society",
+ "11" => "Halifax",
+ "12" => "Hanley Economic Building Society",
+ "13" => "Hinckley and Rugby Building Society",
+ "14" => "Holmesdale Building Society",
+ "15" => "Ipswich Building Society",
+ "16" => "Leeds Building Society",
+ "17" => "Lloyds Bank",
+ "18" => "Mansfield Building Society",
+ "19" => "Market Harborough Building Society",
+ "20" => "Melton Mowbray Building Society",
+ "21" => "Nationwide Building Society",
+ "22" => "Natwest",
+ "23" => "Nedbank Private Wealth",
+ "24" => "Newbury Building Society",
+ "25" => "OneSavings Bank",
+ "26" => "Parity Trust",
+ "27" => "Penrith Building Society",
+ "28" => "Pepper Homeloans",
+ "29" => "Royal Bank of Scotland",
+ "30" => "Santander",
+ "31" => "Skipton Building Society",
+ "32" => "Teachers Building Society",
+ "33" => "The Co-operative Bank",
+ "34" => "Tipton & Coseley Building Society",
+ "35" => "TSB",
+ "36" => "Ulster Bank",
+ "37" => "Virgin Money",
+ "38" => "West Bromwich Building Society",
+ "39" => "Yorkshire Building Society",
+ "40" => "Other",
+ }
+ end
+
def question_number
case @ownershipsch
when 1
diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb
index 5b0d8f17c..ba2ea4fa8 100644
--- a/app/models/sales_log.rb
+++ b/app/models/sales_log.rb
@@ -42,7 +42,7 @@ class SalesLog < Log
}
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org) }
- OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check mortgagelender othtype discounted_sale_value_check].freeze
+ OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check othtype discounted_sale_value_check].freeze
RETIREMENT_AGES = { "M" => 65, "F" => 60, "X" => 65 }.freeze
def lettings?
diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb
index af38106a2..c2844e019 100644
--- a/app/services/imports/sales_logs_import_service.rb
+++ b/app/services/imports/sales_logs_import_service.rb
@@ -189,8 +189,10 @@ module Imports
def rescue_validation_or_raise(sales_log, attributes, previous_status, exception)
if %w[saved submitted-invalid].include?(previous_status)
sales_log.errors.each do |error|
- @logger.warn("Log #{sales_log.old_id}: Removing field #{error.attribute} from log triggering validation: #{error.type}")
- attributes.delete(error.attribute.to_s)
+ unless error.attribute == :type || error.attribute == :ownershipsch
+ @logger.warn("Log #{sales_log.old_id}: Removing field #{error.attribute} from log triggering validation: #{error.type}")
+ attributes.delete(error.attribute.to_s)
+ end
attributes.delete("pcodenk") if error.attribute == :postcode_full
attributes.delete("ppcodenk") if error.attribute == :ppostcode_full
end
@@ -504,6 +506,7 @@ module Imports
def set_default_values(attributes)
attributes["armedforcesspouse"] ||= 7
attributes["hhregres"] ||= 8
+ attributes["hhregresstill"] ||= 7 if attributes["hhregres"] == 1
attributes["disabled"] ||= 3
attributes["wheel"] ||= 3
attributes["hb"] ||= 4
@@ -518,6 +521,7 @@ module Imports
attributes["extrabor"] ||= 3 if attributes["mortgageused"] == 1
attributes["socprevten"] ||= 10 if attributes["ownershipsch"] == 1
attributes["fromprop"] ||= 0 if attributes["ownershipsch"] == 1
+ attributes["mortgagelender"] ||= 0 if attributes["mortgageused"] == 1
# buyer 1 characteristics
attributes["age1_known"] ||= 1
diff --git a/spec/models/form/sales/questions/mortgage_lender_spec.rb b/spec/models/form/sales/questions/mortgage_lender_spec.rb
index 84caef701..811746dbe 100644
--- a/spec/models/form/sales/questions/mortgage_lender_spec.rb
+++ b/spec/models/form/sales/questions/mortgage_lender_spec.rb
@@ -42,6 +42,53 @@ RSpec.describe Form::Sales::Questions::MortgageLender, type: :model do
it "has the correct answer_options" do
expect(question.answer_options).to eq({
+ "" => "Select an option",
+ "0" => "Don’t know",
+ "1" => "Atom Bank",
+ "2" => "Barclays Bank PLC",
+ "3" => "Bath Building Society",
+ "4" => "Buckinghamshire Building Society",
+ "5" => "Cambridge Building Society",
+ "6" => "Coventry Building Society",
+ "7" => "Cumberland Building Society",
+ "8" => "Darlington Building Society",
+ "9" => "Dudley Building Society",
+ "10" => "Ecology Building Society",
+ "11" => "Halifax",
+ "12" => "Hanley Economic Building Society",
+ "13" => "Hinckley and Rugby Building Society",
+ "14" => "Holmesdale Building Society",
+ "15" => "Ipswich Building Society",
+ "16" => "Leeds Building Society",
+ "17" => "Lloyds Bank",
+ "18" => "Mansfield Building Society",
+ "19" => "Market Harborough Building Society",
+ "20" => "Melton Mowbray Building Society",
+ "21" => "Nationwide Building Society",
+ "22" => "Natwest",
+ "23" => "Nedbank Private Wealth",
+ "24" => "Newbury Building Society",
+ "25" => "OneSavings Bank",
+ "26" => "Parity Trust",
+ "27" => "Penrith Building Society",
+ "28" => "Pepper Homeloans",
+ "29" => "Royal Bank of Scotland",
+ "30" => "Santander",
+ "31" => "Skipton Building Society",
+ "32" => "Teachers Building Society",
+ "33" => "The Co-operative Bank",
+ "34" => "Tipton & Coseley Building Society",
+ "35" => "TSB",
+ "36" => "Ulster Bank",
+ "37" => "Virgin Money",
+ "38" => "West Bromwich Building Society",
+ "39" => "Yorkshire Building Society",
+ "40" => "Other",
+ })
+ end
+
+ it "has the correct displayed_answer_options" do
+ expect(question.displayed_answer_options(nil, nil)).to eq({
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb
index d8f4ca5bc..231dc68c4 100644
--- a/spec/models/sales_log_spec.rb
+++ b/spec/models/sales_log_spec.rb
@@ -59,7 +59,6 @@ RSpec.describe SalesLog, type: :model do
purchid
monthly_charges_value_check
old_persons_shared_ownership_value_check
- mortgagelender
othtype
discounted_sale_value_check
proplen
@@ -78,7 +77,6 @@ RSpec.describe SalesLog, type: :model do
purchid
monthly_charges_value_check
old_persons_shared_ownership_value_check
- mortgagelender
othtype
discounted_sale_value_check
address_line2
diff --git a/spec/services/imports/sales_logs_import_service_spec.rb b/spec/services/imports/sales_logs_import_service_spec.rb
index be271778c..e41ffabaf 100644
--- a/spec/services/imports/sales_logs_import_service_spec.rb
+++ b/spec/services/imports/sales_logs_import_service_spec.rb
@@ -167,6 +167,23 @@ RSpec.describe Imports::SalesLogsImportService do
end
end
+ context "when the mortgage lender is not set" do
+ let(:sales_log_id) { "discounted_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:Q34a").content = ""
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "correctly sets mortgage lender and mortgage lender other" do
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.mortgagelender).to be(0)
+ expect(sales_log&.mortgagelenderother).to be_nil
+ end
+ end
+
context "with shared ownership type" do
let(:sales_log_id) { "shared_ownership_sales_log" }
@@ -422,6 +439,33 @@ RSpec.describe Imports::SalesLogsImportService do
end
end
+ context "and setup field has validation error in incomplete log" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//meta:status").content = "saved"
+ sales_log_xml.at_xpath("//xmlns:Q17aStaircase").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:PercentBought").content = "5"
+ sales_log_xml.at_xpath("//xmlns:PercentOwns").content = "40"
+ sales_log_xml.at_xpath("//xmlns:Q17Resale").content = ""
+ sales_log_xml.at_xpath("//xmlns:EXDAY").content = ""
+ sales_log_xml.at_xpath("//xmlns:EXMONTH").content = ""
+ sales_log_xml.at_xpath("//xmlns:EXYEAR").content = ""
+ sales_log_xml.at_xpath("//xmlns:HODAY").content = ""
+ sales_log_xml.at_xpath("//xmlns:HOMONTH").content = ""
+ sales_log_xml.at_xpath("//xmlns:HOYEAR").content = ""
+ end
+
+ it "intercepts the relevant validation error but does not clear setup fields" do
+ expect(logger).to receive(:warn).with(/Log shared_ownership_sales_log: Removing field stairbought from log triggering validation: The minimum increase in equity while staircasing is 10%/)
+ expect { sales_log_service.send(:create_log, sales_log_xml) }
+ .not_to raise_error
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+
+ expect(sales_log.type).to eq(2)
+ end
+ end
+
context "and it has an invalid record with invalid postcodes" do
let(:sales_log_id) { "discounted_ownership_sales_log" }
@@ -735,6 +779,31 @@ RSpec.describe Imports::SalesLogsImportService do
end
end
+ context "when inferring armed forces still" do
+ let(:sales_log_id) { "discounted_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:ArmedF").content = "1 Yes"
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "sets hhregresstill to don't know if not answered" do
+ sales_log_xml.at_xpath("//xmlns:LeftArmedF").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.hhregresstill).to eq(7)
+ end
+
+ it "sets hhregresstill correctly if answered" do
+ sales_log_xml.at_xpath("//xmlns:LeftArmedF").content = "4"
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.hhregresstill).to eq(4)
+ end
+ end
+
context "when inferring disability" do
let(:sales_log_id) { "discounted_ownership_sales_log" }
From 579fa6a969650131c850757c6d635cc11a8d7de2 Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Tue, 21 Mar 2023 17:22:38 +0000
Subject: [PATCH 10/31] CLDC-2134 Rework summary and email (#1451)
* remove column errors from bulk upload email
* summarise setup errors only if there are any
---
...lk_upload_error_summary_table_component.rb | 12 +-
app/mailers/bulk_upload_mailer.rb | 13 --
app/models/bulk_upload.rb | 8 -
...load_error_summary_table_component_spec.rb | 147 +++++++++++-------
spec/mailers/bulk_upload_mailer_spec.rb | 31 +---
5 files changed, 99 insertions(+), 112 deletions(-)
diff --git a/app/components/bulk_upload_error_summary_table_component.rb b/app/components/bulk_upload_error_summary_table_component.rb
index 909fb5f0d..8dddb61d2 100644
--- a/app/components/bulk_upload_error_summary_table_component.rb
+++ b/app/components/bulk_upload_error_summary_table_component.rb
@@ -12,7 +12,7 @@ class BulkUploadErrorSummaryTableComponent < ViewComponent::Base
end
def sorted_errors
- @sorted_errors ||= bulk_upload
+ @sorted_errors ||= setup_errors.presence || bulk_upload
.bulk_upload_errors
.group(:col, :field, :error)
.having("count(*) > ?", display_threshold)
@@ -26,6 +26,16 @@ class BulkUploadErrorSummaryTableComponent < ViewComponent::Base
private
+ def setup_errors
+ @setup_errors ||= bulk_upload
+ .bulk_upload_errors
+ .where(category: "setup")
+ .group(:col, :field, :error)
+ .having("count(*) > ?", display_threshold)
+ .count
+ .sort_by { |el| el[0][0].rjust(3, "0") }
+ end
+
def display_threshold
DISPLAY_THRESHOLD
end
diff --git a/app/mailers/bulk_upload_mailer.rb b/app/mailers/bulk_upload_mailer.rb
index 144acb3e1..d91842bce 100644
--- a/app/mailers/bulk_upload_mailer.rb
+++ b/app/mailers/bulk_upload_mailer.rb
@@ -33,19 +33,7 @@ class BulkUploadMailer < NotifyMailer
)
end
- def columns_with_errors(bulk_upload:)
- array = bulk_upload.columns_with_errors
-
- if array.size > 3
- "#{array.take(3).join(', ')} and more"
- else
- array.join(", ")
- end
- end
-
def send_correct_and_upload_again_mail(bulk_upload:)
- error_description = "We noticed that you have a lot of similar errors in column #{columns_with_errors(bulk_upload:)}. Please correct your data export and upload again."
-
summary_report_link = if BulkUploadErrorSummaryTableComponent.new(bulk_upload:).errors?
summary_bulk_upload_lettings_result_url(bulk_upload)
else
@@ -60,7 +48,6 @@ class BulkUploadMailer < NotifyMailer
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
year_combo: bulk_upload.year_combo,
lettings_or_sales: bulk_upload.log_type,
- error_description:,
summary_report_link:,
},
)
diff --git a/app/models/bulk_upload.rb b/app/models/bulk_upload.rb
index ff334b968..0952b60af 100644
--- a/app/models/bulk_upload.rb
+++ b/app/models/bulk_upload.rb
@@ -30,14 +30,6 @@ class BulkUpload < ApplicationRecord
end
end
- def columns_with_errors
- bulk_upload_errors
- .select(:col)
- .distinct(:col)
- .pluck(:col)
- .sort_by { |col| col.rjust(2, "0") }
- end
-
def general_needs?
needstype == 1
end
diff --git a/spec/components/bulk_upload_error_summary_table_component_spec.rb b/spec/components/bulk_upload_error_summary_table_component_spec.rb
index 4c307515c..32da38119 100644
--- a/spec/components/bulk_upload_error_summary_table_component_spec.rb
+++ b/spec/components/bulk_upload_error_summary_table_component_spec.rb
@@ -9,87 +9,114 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do
stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 0)
end
- context "when no errors" do
- it "does not renders any tables" do
- result = render_inline(component)
- expect(result).not_to have_selector("table")
+ describe "#sorted_errors" do
+ context "when no errors" do
+ it "does not renders any tables" do
+ result = render_inline(component)
+ expect(result).not_to have_selector("table")
+ end
end
- end
- context "when below threshold" do
- before do
- stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 16)
+ context "when below threshold" do
+ before do
+ stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 16)
- create(:bulk_upload_error, bulk_upload:, col: "A", row: 1)
- end
+ create(:bulk_upload_error, bulk_upload:, col: "A", row: 1)
+ end
- it "does not render tables" do
- result = render_inline(component)
- expect(result).to have_selector("table", count: 0)
+ it "does not render tables" do
+ result = render_inline(component)
+ expect(result).to have_selector("table", count: 0)
+ end
end
- end
- context "when there are 2 independent errors" do
- let!(:error_2) { create(:bulk_upload_error, bulk_upload:, col: "B", row: 2) }
- let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1) }
+ context "when there are 2 independent errors" do
+ let!(:error_2) { create(:bulk_upload_error, bulk_upload:, col: "B", row: 2) }
+ let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1) }
- it "renders table for each error" do
- result = render_inline(component)
- expect(result).to have_selector("table", count: 2)
- end
+ it "renders table for each error" do
+ result = render_inline(component)
+ expect(result).to have_selector("table", count: 2)
+ end
- it "renders by col order" do
- result = render_inline(component)
- order = result.css("table thead th:nth-of-type(2)").map(&:content)
- expect(order).to eql(["Column A", "Column B"])
- end
+ it "renders by col order" do
+ result = render_inline(component)
+ order = result.css("table thead th:nth-of-type(2)").map(&:content)
+ expect(order).to eql(["Column A", "Column B"])
+ end
- it "render correct data" do
- result = render_inline(component)
+ it "render correct data" do
+ result = render_inline(component)
- table_1 = result.css("table").first.css("th, td").map(&:content)
+ table_1 = result.css("table").first.css("th, td").map(&:content)
- expect(table_1).to eql([
- bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s,
- "Column A",
- error_1.error,
- "1 error",
- ])
+ expect(table_1).to eql([
+ bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s,
+ "Column A",
+ error_1.error,
+ "1 error",
+ ])
- table_2 = result.css("table")[1].css("th, td").map(&:content)
+ table_2 = result.css("table")[1].css("th, td").map(&:content)
- expect(table_2).to eql([
- bulk_upload.prefix_namespace::RowParser.question_for_field(error_2.field.to_sym).to_s,
- "Column B",
- error_2.error,
- "1 error",
- ])
+ expect(table_2).to eql([
+ bulk_upload.prefix_namespace::RowParser.question_for_field(error_2.field.to_sym).to_s,
+ "Column B",
+ error_2.error,
+ "1 error",
+ ])
+ end
end
- end
- context "when there are 2 grouped errors" do
- let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1, field: "field_1") }
+ context "when there are 2 grouped errors" do
+ let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1, field: "field_1") }
- before do
- create(:bulk_upload_error, bulk_upload:, col: "A", row: 2, field: "field_1")
- end
+ before do
+ create(:bulk_upload_error, bulk_upload:, col: "A", row: 2, field: "field_1")
+ end
+
+ it "renders 1 table combining the errors" do
+ result = render_inline(component)
+ expect(result).to have_selector("table", count: 1)
+ end
- it "renders 1 table combining the errors" do
- result = render_inline(component)
- expect(result).to have_selector("table", count: 1)
+ it "render correct data" do
+ result = render_inline(component)
+
+ table_1 = result.css("table").css("th, td").map(&:content)
+
+ expect(table_1).to eql([
+ bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s,
+ "Column A",
+ error_1.error,
+ "2 errors",
+ ])
+ end
end
- it "render correct data" do
- result = render_inline(component)
+ context "when mix of setup and other errors" do
+ let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1, category: "setup") }
- table_1 = result.css("table").css("th, td").map(&:content)
+ before do
+ create(:bulk_upload_error, bulk_upload:, col: "B", row: 2, category: nil)
+ end
+
+ it "only returns the setup errors" do
+ result = render_inline(component)
+
+ tables = result.css("table")
- expect(table_1).to eql([
- bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s,
- "Column A",
- error_1.error,
- "2 errors",
- ])
+ expect(tables.size).to be(1)
+
+ table = result.css("table").css("th, td").map(&:content)
+
+ expect(table).to eql([
+ bulk_upload.prefix_namespace::RowParser.question_for_field(error_1.field.to_sym).to_s,
+ "Column A",
+ error_1.error,
+ "1 error",
+ ])
+ end
end
end
diff --git a/spec/mailers/bulk_upload_mailer_spec.rb b/spec/mailers/bulk_upload_mailer_spec.rb
index 9f59de365..2e4337328 100644
--- a/spec/mailers/bulk_upload_mailer_spec.rb
+++ b/spec/mailers/bulk_upload_mailer_spec.rb
@@ -116,7 +116,7 @@ RSpec.describe BulkUploadMailer do
create(:bulk_upload_error, bulk_upload:, col: "B")
end
- it "sends correctly formed email with A, B" do
+ it "sends correctly formed email" do
expect(notify_client).to receive(:send_email).with(
email_address: user.email,
template_id: described_class::BULK_UPLOAD_FAILED_CSV_ERRORS_TEMPLATE_ID,
@@ -125,7 +125,6 @@ RSpec.describe BulkUploadMailer do
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
year_combo: bulk_upload.year_combo,
lettings_or_sales: bulk_upload.log_type,
- error_description: "We noticed that you have a lot of similar errors in column A, B. Please correct your data export and upload again.",
summary_report_link: "http://localhost:3000/lettings-logs/bulk-upload-results/#{bulk_upload.id}",
},
)
@@ -133,33 +132,5 @@ RSpec.describe BulkUploadMailer do
mailer.send_correct_and_upload_again_mail(bulk_upload:)
end
end
-
- context "when 4 columns with errors" do
- before do
- stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 0)
-
- create(:bulk_upload_error, bulk_upload:, col: "A")
- create(:bulk_upload_error, bulk_upload:, col: "B")
- create(:bulk_upload_error, bulk_upload:, col: "C")
- create(:bulk_upload_error, bulk_upload:, col: "D")
- end
-
- it "sends correctly formed email with A, B, C and more" do
- expect(notify_client).to receive(:send_email).with(
- email_address: user.email,
- template_id: described_class::BULK_UPLOAD_FAILED_CSV_ERRORS_TEMPLATE_ID,
- personalisation: {
- filename: bulk_upload.filename,
- upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
- year_combo: bulk_upload.year_combo,
- lettings_or_sales: bulk_upload.log_type,
- error_description: "We noticed that you have a lot of similar errors in column A, B, C and more. Please correct your data export and upload again.",
- summary_report_link: "http://localhost:3000/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary",
- },
- )
-
- mailer.send_correct_and_upload_again_mail(bulk_upload:)
- end
- end
end
end
From 1a5d9fc14b7a417a359cc95754a5c6768f2b4f3c Mon Sep 17 00:00:00 2001
From: Jack <113976590+bibblobcode@users.noreply.github.com>
Date: Wed, 22 Mar 2023 13:00:03 +0000
Subject: [PATCH 11/31] [CLDC-2068] Add UPRN questions to lettings (#1432)
* Update CYA page
* Update UPRN derived fields
* Update sales' UPRN questions
* Add UPRN lettings questions
* Fix spec
---
...swers_summary_list_card_component.html.erb | 16 +++-
.../lettings_log_variables.rb | 21 +++++
app/models/form/lettings/pages/address.rb | 24 +++++
.../pages/property_local_authority.rb | 8 ++
app/models/form/lettings/pages/uprn.rb | 28 ++++++
.../form/lettings/pages/uprn_confirmation.rb | 17 ++++
app/models/form/lettings/pages/uprn_known.rb | 16 ++++
.../form/lettings/questions/address_line1.rb | 38 ++++++++
.../form/lettings/questions/address_line2.rb | 13 +++
app/models/form/lettings/questions/county.rb | 13 +++
app/models/form/lettings/questions/la.rb | 4 +
.../questions/postcode_for_full_address.rb | 25 +++++
.../form/lettings/questions/town_or_city.rb | 13 +++
app/models/form/lettings/questions/uprn.rb | 35 +++++++
.../lettings/questions/uprn_confirmation.rb | 34 +++++++
.../form/lettings/questions/uprn_known.rb | 21 +++++
.../subsections/property_information.rb | 19 +++-
.../form/sales/questions/address_line1.rb | 1 +
app/models/form/sales/questions/uprn.rb | 1 +
app/models/lettings_log.rb | 5 +
app/models/log.rb | 1 +
.../form/_check_answers_summary_list.html.erb | 2 +-
.../form/lettings/pages/address_spec.rb | 73 +++++++++++++++
.../pages/property_local_authority_spec.rb | 77 ++++++++++++++++
.../lettings/pages/uprn_confirmation_spec.rb | 59 ++++++++++++
.../form/lettings/pages/uprn_known_spec.rb | 51 ++++++++++
spec/models/form/lettings/pages/uprn_spec.rb | 81 ++++++++++++++++
.../lettings/questions/address_line1_spec.rb | 79 ++++++++++++++++
.../lettings/questions/address_line2_spec.rb | 49 ++++++++++
.../form/lettings/questions/county_spec.rb | 49 ++++++++++
.../models/form/lettings/questions/la_spec.rb | 30 ++++++
.../postcode_for_full_address_spec.rb | 62 +++++++++++++
.../lettings/questions/town_or_city_spec.rb | 49 ++++++++++
.../questions/uprn_confirmation_spec.rb | 90 ++++++++++++++++++
.../lettings/questions/uprn_known_spec.rb | 59 ++++++++++++
.../form/lettings/questions/uprn_spec.rb | 92 +++++++++++++++++++
.../subsections/property_information_spec.rb | 83 ++++++++++++-----
.../sales/questions/address_line1_spec.rb | 4 +
spec/models/form/sales/questions/uprn_spec.rb | 4 +
spec/models/lettings_log_spec.rb | 57 ++++++++++++
spec/models/sales_log_spec.rb | 10 +-
41 files changed, 1382 insertions(+), 31 deletions(-)
create mode 100644 app/models/form/lettings/pages/address.rb
create mode 100644 app/models/form/lettings/pages/uprn.rb
create mode 100644 app/models/form/lettings/pages/uprn_confirmation.rb
create mode 100644 app/models/form/lettings/pages/uprn_known.rb
create mode 100644 app/models/form/lettings/questions/address_line1.rb
create mode 100644 app/models/form/lettings/questions/address_line2.rb
create mode 100644 app/models/form/lettings/questions/county.rb
create mode 100644 app/models/form/lettings/questions/postcode_for_full_address.rb
create mode 100644 app/models/form/lettings/questions/town_or_city.rb
create mode 100644 app/models/form/lettings/questions/uprn.rb
create mode 100644 app/models/form/lettings/questions/uprn_confirmation.rb
create mode 100644 app/models/form/lettings/questions/uprn_known.rb
create mode 100644 spec/models/form/lettings/pages/address_spec.rb
create mode 100644 spec/models/form/lettings/pages/property_local_authority_spec.rb
create mode 100644 spec/models/form/lettings/pages/uprn_confirmation_spec.rb
create mode 100644 spec/models/form/lettings/pages/uprn_known_spec.rb
create mode 100644 spec/models/form/lettings/pages/uprn_spec.rb
create mode 100644 spec/models/form/lettings/questions/address_line1_spec.rb
create mode 100644 spec/models/form/lettings/questions/address_line2_spec.rb
create mode 100644 spec/models/form/lettings/questions/county_spec.rb
create mode 100644 spec/models/form/lettings/questions/postcode_for_full_address_spec.rb
create mode 100644 spec/models/form/lettings/questions/town_or_city_spec.rb
create mode 100644 spec/models/form/lettings/questions/uprn_confirmation_spec.rb
create mode 100644 spec/models/form/lettings/questions/uprn_known_spec.rb
create mode 100644 spec/models/form/lettings/questions/uprn_spec.rb
diff --git a/app/components/check_answers_summary_list_card_component.html.erb b/app/components/check_answers_summary_list_card_component.html.erb
index 3b4c4978a..31c3bffac 100644
--- a/app/components/check_answers_summary_list_card_component.html.erb
+++ b/app/components/check_answers_summary_list_card_component.html.erb
@@ -12,16 +12,22 @@
<% summary_list.row do |row| %>
<% row.key { get_question_label(question) } %>
<% row.value do %>
- <%= get_answer_label(question) %>
+ <%= simple_format(
+ get_answer_label(question),
+ wrapper_tag: "span",
+ class: "govuk-!-margin-right-4",
+ ) %>
<% extra_value = question.get_extra_check_answer_value(log) %>
- <% if extra_value %>
- <%= extra_value %>
+ <% if extra_value && question.answer_label(log).present? %>
+ <%= simple_format(
+ extra_value,
+ wrapper_tag: "span",
+ class: "govuk-!-font-weight-regular app-!-colour-muted",
+ ) %>
<% end %>
-
-
<% question.get_inferred_answers(log).each do |inferred_answer| %>
<%= inferred_answer %>
<% end %>
diff --git a/app/models/derived_variables/lettings_log_variables.rb b/app/models/derived_variables/lettings_log_variables.rb
index d42fb3903..aae49422d 100644
--- a/app/models/derived_variables/lettings_log_variables.rb
+++ b/app/models/derived_variables/lettings_log_variables.rb
@@ -94,6 +94,17 @@ module DerivedVariables::LettingsLogVariables
self.vacdays = property_vacant_days
set_housingneeds_fields if housingneeds?
+
+ if uprn_known&.zero?
+ self.uprn = nil
+ end
+
+ if uprn_confirmed&.zero?
+ self.uprn = nil
+ self.uprn_known = 0
+ end
+
+ reset_address_fields! if is_supported_housing?
end
private
@@ -229,4 +240,14 @@ private
self.housingneeds_g = 0
self.housingneeds_h = 0
end
+
+ def reset_address_fields!
+ self.uprn = nil
+ self.uprn_known = nil
+ self.uprn_confirmed = nil
+ self.address_line1 = nil
+ self.address_line2 = nil
+ self.town_or_city = nil
+ self.county = nil
+ end
end
diff --git a/app/models/form/lettings/pages/address.rb b/app/models/form/lettings/pages/address.rb
new file mode 100644
index 000000000..6f88bad0d
--- /dev/null
+++ b/app/models/form/lettings/pages/address.rb
@@ -0,0 +1,24 @@
+class Form::Lettings::Pages::Address < ::Form::Page
+ def initialize(id, hsh, subsection)
+ super
+ @id = "address"
+ @header = "What is the property's address?"
+ end
+
+ def questions
+ @questions ||= [
+ Form::Lettings::Questions::AddressLine1.new(nil, nil, self),
+ Form::Lettings::Questions::AddressLine2.new(nil, nil, self),
+ Form::Lettings::Questions::TownOrCity.new(nil, nil, self),
+ Form::Lettings::Questions::County.new(nil, nil, self),
+ Form::Lettings::Questions::PostcodeForFullAddress.new(nil, nil, self),
+ ]
+ end
+
+ def routed_to?(log, _current_user = nil)
+ return false if log.uprn_known.nil?
+ return false if log.is_supported_housing?
+
+ log.uprn_confirmed != 1 || log.uprn_known.zero?
+ end
+end
diff --git a/app/models/form/lettings/pages/property_local_authority.rb b/app/models/form/lettings/pages/property_local_authority.rb
index 2c64e3628..7692fd376 100644
--- a/app/models/form/lettings/pages/property_local_authority.rb
+++ b/app/models/form/lettings/pages/property_local_authority.rb
@@ -8,4 +8,12 @@ class Form::Lettings::Pages::PropertyLocalAuthority < ::Form::Page
def questions
@questions ||= [Form::Lettings::Questions::La.new(nil, nil, self)]
end
+
+ def routed_to?(log, _current_user = nil)
+ return false if log.uprn_known.nil? && form.start_date.year >= 2023
+ return false if log.is_la_inferred?
+ return false if log.is_supported_housing?
+
+ true
+ end
end
diff --git a/app/models/form/lettings/pages/uprn.rb b/app/models/form/lettings/pages/uprn.rb
new file mode 100644
index 000000000..7b6b90f1a
--- /dev/null
+++ b/app/models/form/lettings/pages/uprn.rb
@@ -0,0 +1,28 @@
+class Form::Lettings::Pages::Uprn < ::Form::Page
+ def initialize(id, hsh, subsection)
+ super
+ @id = "uprn"
+ end
+
+ def questions
+ @questions ||= [
+ Form::Lettings::Questions::Uprn.new(nil, nil, self),
+ ]
+ end
+
+ def routed_to?(log, _current_user = nil)
+ return false if log.is_supported_housing?
+
+ log.uprn_known == 1
+ end
+
+ def skip_text
+ "Enter address instead"
+ end
+
+ def skip_href(log = nil)
+ return unless log
+
+ "/#{log.model_name.param_key.dasherize}s/#{log.id}/address"
+ end
+end
diff --git a/app/models/form/lettings/pages/uprn_confirmation.rb b/app/models/form/lettings/pages/uprn_confirmation.rb
new file mode 100644
index 000000000..26cde2d97
--- /dev/null
+++ b/app/models/form/lettings/pages/uprn_confirmation.rb
@@ -0,0 +1,17 @@
+class Form::Lettings::Pages::UprnConfirmation < ::Form::Page
+ def initialize(id, hsh, subsection)
+ super
+ @id = "uprn_confirmation"
+ @header = "We found an address that might be this property"
+ end
+
+ def questions
+ @questions ||= [
+ Form::Lettings::Questions::UprnConfirmation.new(nil, nil, self),
+ ]
+ end
+
+ def routed_to?(log, _current_user = nil)
+ log.uprn.present? && log.uprn_known == 1
+ end
+end
diff --git a/app/models/form/lettings/pages/uprn_known.rb b/app/models/form/lettings/pages/uprn_known.rb
new file mode 100644
index 000000000..1ded1ba82
--- /dev/null
+++ b/app/models/form/lettings/pages/uprn_known.rb
@@ -0,0 +1,16 @@
+class Form::Lettings::Pages::UprnKnown < ::Form::Page
+ def initialize(id, hsh, subsection)
+ super
+ @id = "uprn_known"
+ end
+
+ def questions
+ @questions ||= [
+ Form::Lettings::Questions::UprnKnown.new(nil, nil, self),
+ ]
+ end
+
+ def routed_to?(log, _current_user = nil)
+ !log.is_supported_housing?
+ end
+end
diff --git a/app/models/form/lettings/questions/address_line1.rb b/app/models/form/lettings/questions/address_line1.rb
new file mode 100644
index 000000000..6f82edf45
--- /dev/null
+++ b/app/models/form/lettings/questions/address_line1.rb
@@ -0,0 +1,38 @@
+class Form::Lettings::Questions::AddressLine1 < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "address_line1"
+ @check_answer_label = "Address"
+ @header = "Address line 1"
+ @type = "text"
+ @plain_label = true
+ @question_number = 12
+ end
+
+ def hidden_in_check_answers?(log, _current_user = nil)
+ return true if log.uprn_known.nil?
+ return false if log.uprn_known&.zero?
+ return true if log.uprn_confirmed.nil? && log.uprn.present?
+ return true if log.uprn_known == 1 && log.uprn.blank?
+
+ log.uprn_confirmed == 1
+ end
+
+ def answer_label(log, _current_user = nil)
+ [
+ log.address_line1,
+ log.address_line2,
+ log.postcode_full,
+ log.town_or_city,
+ log.county,
+ ].select(&:present?).join("\n")
+ end
+
+ def get_extra_check_answer_value(log)
+ return unless log.is_la_inferred?
+
+ la = LocalAuthority.find_by(code: log.la)&.name
+
+ la.presence
+ end
+end
diff --git a/app/models/form/lettings/questions/address_line2.rb b/app/models/form/lettings/questions/address_line2.rb
new file mode 100644
index 000000000..16f7c8336
--- /dev/null
+++ b/app/models/form/lettings/questions/address_line2.rb
@@ -0,0 +1,13 @@
+class Form::Lettings::Questions::AddressLine2 < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "address_line2"
+ @header = "Address line 2 (optional)"
+ @type = "text"
+ @plain_label = true
+ end
+
+ def hidden_in_check_answers?(_log = nil, _current_user = nil)
+ true
+ end
+end
diff --git a/app/models/form/lettings/questions/county.rb b/app/models/form/lettings/questions/county.rb
new file mode 100644
index 000000000..360c0966c
--- /dev/null
+++ b/app/models/form/lettings/questions/county.rb
@@ -0,0 +1,13 @@
+class Form::Lettings::Questions::County < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "county"
+ @header = "County (optional)"
+ @type = "text"
+ @plain_label = true
+ end
+
+ def hidden_in_check_answers?(_log = nil, _current_user = nil)
+ true
+ end
+end
diff --git a/app/models/form/lettings/questions/la.rb b/app/models/form/lettings/questions/la.rb
index 3cafda054..b70e7590b 100644
--- a/app/models/form/lettings/questions/la.rb
+++ b/app/models/form/lettings/questions/la.rb
@@ -13,4 +13,8 @@ class Form::Lettings::Questions::La < ::Form::Question
def answer_options
{ "" => "Select an option" }.merge(LocalAuthority.active(form.start_date).england.map { |la| [la.code, la.name] }.to_h)
end
+
+ def hidden_in_check_answers?(log, _current_user = nil)
+ log.startdate && log.startdate.year >= 2023 && log.is_la_inferred?
+ end
end
diff --git a/app/models/form/lettings/questions/postcode_for_full_address.rb b/app/models/form/lettings/questions/postcode_for_full_address.rb
new file mode 100644
index 000000000..015abc2e8
--- /dev/null
+++ b/app/models/form/lettings/questions/postcode_for_full_address.rb
@@ -0,0 +1,25 @@
+class Form::Lettings::Questions::PostcodeForFullAddress < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "postcode_full"
+ @header = "Postcode"
+ @type = "text"
+ @width = 5
+ @inferred_check_answers_value = [{
+ "condition" => {
+ "pcodenk" => 1,
+ },
+ "value" => "Not known",
+ }]
+ @inferred_answers = {
+ "la" => {
+ "is_la_inferred" => true,
+ },
+ }
+ @plain_label = true
+ end
+
+ def hidden_in_check_answers?(_log = nil, _current_user = nil)
+ true
+ end
+end
diff --git a/app/models/form/lettings/questions/town_or_city.rb b/app/models/form/lettings/questions/town_or_city.rb
new file mode 100644
index 000000000..f1eac8dff
--- /dev/null
+++ b/app/models/form/lettings/questions/town_or_city.rb
@@ -0,0 +1,13 @@
+class Form::Lettings::Questions::TownOrCity < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "town_or_city"
+ @header = "Town or city"
+ @type = "text"
+ @plain_label = true
+ end
+
+ def hidden_in_check_answers?(_log = nil, _current_user = nil)
+ true
+ end
+end
diff --git a/app/models/form/lettings/questions/uprn.rb b/app/models/form/lettings/questions/uprn.rb
new file mode 100644
index 000000000..efe9a4ea4
--- /dev/null
+++ b/app/models/form/lettings/questions/uprn.rb
@@ -0,0 +1,35 @@
+class Form::Lettings::Questions::Uprn < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "uprn"
+ @check_answer_label = "UPRN"
+ @header = "What is the property's UPRN"
+ @type = "text"
+ @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355."
+ @width = 10
+ @question_number = 11
+ end
+
+ def unanswered_error_message
+ I18n.t("validations.property.uprn.invalid")
+ end
+
+ def get_extra_check_answer_value(log)
+ value = [
+ log.address_line1,
+ log.address_line2,
+ log.town_or_city,
+ log.county,
+ log.postcode_full,
+ (LocalAuthority.find_by(code: log.la)&.name if log.la.present?),
+ ].select(&:present?)
+
+ return unless value.any?
+
+ "\n\n#{value.join("\n")}"
+ end
+
+ def hidden_in_check_answers?(log, _current_user = nil)
+ log.uprn_known != 1
+ end
+end
diff --git a/app/models/form/lettings/questions/uprn_confirmation.rb b/app/models/form/lettings/questions/uprn_confirmation.rb
new file mode 100644
index 000000000..5b7bbd535
--- /dev/null
+++ b/app/models/form/lettings/questions/uprn_confirmation.rb
@@ -0,0 +1,34 @@
+class Form::Lettings::Questions::UprnConfirmation < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "uprn_confirmed"
+ @header = "Is this the property address?"
+ @type = "radio"
+ @answer_options = ANSWER_OPTIONS
+ @check_answer_label = "Is this the right address?"
+ end
+
+ ANSWER_OPTIONS = {
+ "1" => { "value" => "Yes" },
+ "0" => { "value" => "No, I want to enter the address manually" },
+ }.freeze
+
+ def notification_banner(log = nil)
+ return unless log&.uprn
+
+ {
+ title: "UPRN: #{log.uprn}",
+ heading: [
+ log.address_line1,
+ log.address_line2,
+ log.postcode_full,
+ log.town_or_city,
+ log.county,
+ ].select(&:present?).join("\n"),
+ }
+ end
+
+ def hidden_in_check_answers?(log, _current_user = nil)
+ log.uprn_known != 1 || log.uprn_confirmed.present?
+ end
+end
diff --git a/app/models/form/lettings/questions/uprn_known.rb b/app/models/form/lettings/questions/uprn_known.rb
new file mode 100644
index 000000000..6e3ce0302
--- /dev/null
+++ b/app/models/form/lettings/questions/uprn_known.rb
@@ -0,0 +1,21 @@
+class Form::Lettings::Questions::UprnKnown < ::Form::Question
+ def initialize(id, hsh, page)
+ super
+ @id = "uprn_known"
+ @check_answer_label = "UPRN known?"
+ @header = "Do you know the property UPRN?"
+ @type = "radio"
+ @answer_options = ANSWER_OPTIONS
+ @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.
+ You can continue without the UPRN, but it means we will need you to enter the address of the property."
+ end
+
+ ANSWER_OPTIONS = {
+ "1" => { "value" => "Yes" },
+ "0" => { "value" => "No" },
+ }.freeze
+
+ def unanswered_error_message
+ I18n.t("validations.property.uprn_known.invalid")
+ end
+end
diff --git a/app/models/form/lettings/subsections/property_information.rb b/app/models/form/lettings/subsections/property_information.rb
index 6e20ea7cf..c20c2b27c 100644
--- a/app/models/form/lettings/subsections/property_information.rb
+++ b/app/models/form/lettings/subsections/property_information.rb
@@ -8,7 +8,7 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
def pages
@pages ||= [
- Form::Lettings::Pages::PropertyPostcode.new(nil, nil, self),
+ uprn_questions,
Form::Lettings::Pages::PropertyLocalAuthority.new(nil, nil, self),
Form::Lettings::Pages::FirstTimePropertyLetAsSocialHousing.new(nil, nil, self),
Form::Lettings::Pages::PropertyLetType.new(nil, nil, self),
@@ -25,7 +25,22 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
Form::Lettings::Pages::NewBuildHandoverDate.new(nil, nil, self),
Form::Lettings::Pages::PropertyMajorRepairs.new(nil, nil, self),
Form::Lettings::Pages::PropertyMajorRepairsValueCheck.new(nil, nil, self),
- ].compact
+ ].flatten.compact
+ end
+
+ def uprn_questions
+ if form.start_date.year >= 2023
+ [
+ Form::Lettings::Pages::UprnKnown.new(nil, nil, self),
+ Form::Lettings::Pages::Uprn.new(nil, nil, self),
+ Form::Lettings::Pages::UprnConfirmation.new(nil, nil, self),
+ Form::Lettings::Pages::Address.new(nil, nil, self),
+ ]
+ else
+ [
+ Form::Lettings::Pages::PropertyPostcode.new(nil, nil, self),
+ ]
+ end
end
def displayed_in_tasklist?(log)
diff --git a/app/models/form/sales/questions/address_line1.rb b/app/models/form/sales/questions/address_line1.rb
index e8ccb17c0..2dd3a734e 100644
--- a/app/models/form/sales/questions/address_line1.rb
+++ b/app/models/form/sales/questions/address_line1.rb
@@ -6,6 +6,7 @@ class Form::Sales::Questions::AddressLine1 < ::Form::Question
@header = "Address line 1"
@type = "text"
@plain_label = true
+ @question_number = 15
end
def hidden_in_check_answers?(log, _current_user = nil)
diff --git a/app/models/form/sales/questions/uprn.rb b/app/models/form/sales/questions/uprn.rb
index 2c0b66dc8..7967a2035 100644
--- a/app/models/form/sales/questions/uprn.rb
+++ b/app/models/form/sales/questions/uprn.rb
@@ -7,6 +7,7 @@ class Form::Sales::Questions::Uprn < ::Form::Question
@type = "text"
@hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355."
@width = 10
+ @question_number = 14
end
def unanswered_error_message
diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb
index f8c817c56..f96c41c88 100644
--- a/app/models/lettings_log.rb
+++ b/app/models/lettings_log.rb
@@ -32,6 +32,7 @@ class LettingsLog < Log
before_validation :reset_location_fields!, unless: :postcode_known?
before_validation :reset_previous_location_fields!, unless: :previous_postcode_known?
before_validation :set_derived_fields!
+ after_validation :process_uprn_change!, if: :should_process_uprn_change?
belongs_to :scheme, optional: true
belongs_to :location, optional: true
@@ -679,4 +680,8 @@ private
def unknown_housingneeds?
housingneeds == 3
end
+
+ def should_process_uprn_change?
+ uprn_changed? && startdate && startdate.year >= 2023
+ end
end
diff --git a/app/models/log.rb b/app/models/log.rb
index 34c920bd5..3ecc02754 100644
--- a/app/models/log.rb
+++ b/app/models/log.rb
@@ -45,6 +45,7 @@ class Log < ApplicationRecord
self.address_line2 = presenter.address_line2
self.town_or_city = presenter.town_or_city
self.postcode_full = presenter.postcode
+ self.county = nil
process_postcode_changes!
end
end
diff --git a/app/views/form/_check_answers_summary_list.html.erb b/app/views/form/_check_answers_summary_list.html.erb
index 71fe9cd97..653cd610d 100644
--- a/app/views/form/_check_answers_summary_list.html.erb
+++ b/app/views/form/_check_answers_summary_list.html.erb
@@ -9,7 +9,7 @@
class: "govuk-!-margin-right-4",
) %>
<% extra_value = question.get_extra_check_answer_value(@log) %>
- <% if extra_value && question.answer_label(lettings_log, current_user).present? %>
+ <% if extra_value && question.answer_label(@log, current_user).present? %>
<%= simple_format(
extra_value,
wrapper_tag: "span",
diff --git a/spec/models/form/lettings/pages/address_spec.rb b/spec/models/form/lettings/pages/address_spec.rb
new file mode 100644
index 000000000..e4cf044b8
--- /dev/null
+++ b/spec/models/form/lettings/pages/address_spec.rb
@@ -0,0 +1,73 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::Address, type: :model do
+ subject(:page) { described_class.new(page_id, page_definition, subsection) }
+
+ let(:page_id) { nil }
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(%w[address_line1 address_line2 town_or_city county postcode_full])
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("address")
+ end
+
+ it "has the correct header" do
+ expect(page.header).to eq("What is the property's address?")
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be_nil
+ end
+
+ it "has correct depends_on" do
+ expect(page.depends_on).to be_nil
+ end
+
+ describe "has correct routed_to?" do
+ context "when uprn_known == nil" do
+ let(:log) { create(:lettings_log, uprn_known: nil) }
+
+ it "returns false" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+
+ context "when uprn_confirmed != 1" do
+ let(:log) do
+ create(:lettings_log, uprn_known: 1, uprn_confirmed: 0)
+ end
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when uprn_known == 0" do
+ let(:log) do
+ create(:lettings_log, uprn_known: 0, uprn_confirmed: 0)
+ end
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when uprn_confirmed == 1 && uprn_known != 0" do
+ let(:log) do
+ create(:lettings_log, uprn_known: 1, uprn_confirmed: 1)
+ end
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/pages/property_local_authority_spec.rb b/spec/models/form/lettings/pages/property_local_authority_spec.rb
new file mode 100644
index 000000000..5b5ee95eb
--- /dev/null
+++ b/spec/models/form/lettings/pages/property_local_authority_spec.rb
@@ -0,0 +1,77 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::PropertyLocalAuthority, type: :model do
+ subject(:page) { described_class.new(page_id, page_definition, subsection) }
+
+ let(:page_id) { nil }
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date:)) }
+ let(:start_date) { Time.utc(2022, 4, 1) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(
+ %w[
+ la
+ ],
+ )
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("property_local_authority")
+ end
+
+ it "has the correct header" do
+ expect(page.header).to be_nil
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be_nil
+ end
+
+ it "has the correct depends_on" do
+ expect(page.depends_on).to match([{ "is_general_needs?" => true, "is_la_inferred" => false }])
+ end
+
+ describe "has correct routed_to?" do
+ context "when start_date < 2023" do
+ let(:log) { create(:lettings_log, uprn_known: 1) }
+ let(:start_date) { Time.utc(2022, 2, 8) }
+
+ it "returns false" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when start_date >= 2023" do
+ let(:log) { create(:lettings_log, uprn_known: 1) }
+ let(:start_date) { Time.utc(2023, 2, 8) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when start_date < 2023 and uprn_known: nil" do
+ let(:log) { create(:lettings_log, uprn_known: nil) }
+ let(:start_date) { Time.utc(2023, 2, 8) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+
+ context "when is_la_inferred: true" do
+ before do
+ allow(log).to receive(:is_la_inferred?).and_return(true)
+ end
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/pages/uprn_confirmation_spec.rb b/spec/models/form/lettings/pages/uprn_confirmation_spec.rb
new file mode 100644
index 000000000..e1c6a587d
--- /dev/null
+++ b/spec/models/form/lettings/pages/uprn_confirmation_spec.rb
@@ -0,0 +1,59 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::UprnConfirmation, type: :model do
+ subject(:page) { described_class.new(page_id, page_definition, subsection) }
+
+ let(:page_id) { nil }
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(%w[uprn_confirmed])
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("uprn_confirmation")
+ end
+
+ it "has the correct header" do
+ expect(page.header).to eq("We found an address that might be this property")
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be_nil
+ end
+
+ it "has correct depends_on" do
+ expect(page.depends_on).to be_nil
+ end
+
+ describe "has correct routed_to?" do
+ context "when uprn present && uprn_known == 1 " do
+ let(:log) { create(:lettings_log, uprn_known: 1, uprn: "123456789") }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when uprn = nil" do
+ let(:log) { create(:lettings_log, uprn_known: 1, uprn: nil) }
+
+ it "returns false" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+
+ context "when uprn_known == 0" do
+ let(:log) { create(:lettings_log, uprn_known: 0, uprn: "123456789") }
+
+ it "returns false" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/pages/uprn_known_spec.rb b/spec/models/form/lettings/pages/uprn_known_spec.rb
new file mode 100644
index 000000000..27b893a5c
--- /dev/null
+++ b/spec/models/form/lettings/pages/uprn_known_spec.rb
@@ -0,0 +1,51 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::UprnKnown, type: :model do
+ subject(:page) { described_class.new(page_id, page_definition, subsection) }
+
+ let(:page_id) { nil }
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(%w[uprn_known])
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("uprn_known")
+ end
+
+ it "has the correct header" do
+ expect(page.header).to be_nil
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be_nil
+ end
+
+ it "has correct depends_on" do
+ expect(page.depends_on).to be_nil
+ end
+
+ describe "has correct routed_to?" do
+ context "when needstype != 2" do
+ let(:log) { create(:lettings_log, needstype: nil) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when needstype == 2" do
+ let(:log) { create(:lettings_log, needstype: 2) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/pages/uprn_spec.rb b/spec/models/form/lettings/pages/uprn_spec.rb
new file mode 100644
index 000000000..7b480b6b2
--- /dev/null
+++ b/spec/models/form/lettings/pages/uprn_spec.rb
@@ -0,0 +1,81 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Pages::Uprn, type: :model do
+ subject(:page) { described_class.new(page_id, page_definition, subsection) }
+
+ let(:page_id) { nil }
+ let(:page_definition) { nil }
+ let(:subsection) { instance_double(Form::Subsection) }
+
+ it "has correct subsection" do
+ expect(page.subsection).to eq(subsection)
+ end
+
+ it "has correct questions" do
+ expect(page.questions.map(&:id)).to eq(%w[uprn])
+ end
+
+ it "has the correct id" do
+ expect(page.id).to eq("uprn")
+ end
+
+ it "has the correct header" do
+ expect(page.header).to be_nil
+ end
+
+ it "has the correct description" do
+ expect(page.description).to be_nil
+ end
+
+ it "has correct depends_on" do
+ expect(page.depends_on).to be_nil
+ end
+
+ it "has correct skip_text" do
+ expect(page.skip_text).to eq("Enter address instead")
+ end
+
+ describe "has correct routed_to?" do
+ context "when uprn_known != 1" do
+ let(:log) { create(:lettings_log, uprn_known: 0) }
+
+ it "returns false" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+
+ context "when uprn_known == 1" do
+ let(:log) { create(:lettings_log, uprn_known: 1) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(true)
+ end
+ end
+
+ context "when needstype == 2" do
+ let(:log) { create(:lettings_log, uprn_known: 1, needstype: 2) }
+
+ it "returns true" do
+ expect(page.routed_to?(log)).to eq(false)
+ end
+ end
+ end
+
+ describe "has correct skip_href" do
+ context "when log is nil" do
+ it "is nil" do
+ expect(page.skip_href).to be_nil
+ end
+ end
+
+ context "when log is present" do
+ let(:log) { create(:lettings_log) }
+
+ it "points to address page" do
+ expect(page.skip_href(log)).to eq(
+ "/lettings-logs/#{log.id}/address",
+ )
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/questions/address_line1_spec.rb b/spec/models/form/lettings/questions/address_line1_spec.rb
new file mode 100644
index 000000000..781b0a748
--- /dev/null
+++ b/spec/models/form/lettings/questions/address_line1_spec.rb
@@ -0,0 +1,79 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::AddressLine1, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("address_line1")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Address line 1")
+ end
+
+ it "has the correct question_number" do
+ expect(question.question_number).to eq(12)
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to eq("Address")
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct inferred check answers value" do
+ expect(question.inferred_check_answers_value).to be_nil
+ end
+
+ it "has the correct check_answers_card_number" do
+ expect(question.check_answers_card_number).to be_nil
+ end
+
+ describe "has the correct get_extra_check_answer_value" do
+ context "when la is not present" do
+ let(:log) { create(:lettings_log, la: nil) }
+
+ it "returns nil" do
+ expect(question.get_extra_check_answer_value(log)).to be_nil
+ end
+ end
+
+ context "when la is present but not inferred" do
+ let(:log) { create(:lettings_log, la: "E09000003", is_la_inferred: false) }
+
+ it "returns nil" do
+ expect(question.get_extra_check_answer_value(log)).to be_nil
+ end
+ end
+
+ context "when la is present but inferred" do
+ let(:log) { create(:lettings_log, la: "E09000003") }
+
+ before do
+ allow(log).to receive(:is_la_inferred?).and_return(true)
+ end
+
+ it "returns the la" do
+ expect(question.get_extra_check_answer_value(log)).to eq("Barnet")
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/questions/address_line2_spec.rb b/spec/models/form/lettings/questions/address_line2_spec.rb
new file mode 100644
index 000000000..4ac51a231
--- /dev/null
+++ b/spec/models/form/lettings/questions/address_line2_spec.rb
@@ -0,0 +1,49 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::AddressLine2, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("address_line2")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Address line 2 (optional)")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to be_nil
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct inferred check answers value" do
+ expect(question.inferred_check_answers_value).to be_nil
+ end
+
+ it "has the correct check_answers_card_number" do
+ expect(question.check_answers_card_number).to be_nil
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers?).to eq(true)
+ end
+end
diff --git a/spec/models/form/lettings/questions/county_spec.rb b/spec/models/form/lettings/questions/county_spec.rb
new file mode 100644
index 000000000..cf8f814e4
--- /dev/null
+++ b/spec/models/form/lettings/questions/county_spec.rb
@@ -0,0 +1,49 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::County, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("county")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("County (optional)")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to be_nil
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct inferred check answers value" do
+ expect(question.inferred_check_answers_value).to be_nil
+ end
+
+ it "has the correct check_answers_card_number" do
+ expect(question.check_answers_card_number).to be_nil
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers?).to eq(true)
+ end
+end
diff --git a/spec/models/form/lettings/questions/la_spec.rb b/spec/models/form/lettings/questions/la_spec.rb
index f73a29660..3b5e30977 100644
--- a/spec/models/form/lettings/questions/la_spec.rb
+++ b/spec/models/form/lettings/questions/la_spec.rb
@@ -315,4 +315,34 @@ RSpec.describe Form::Lettings::Questions::La, type: :model do
"E06000065" => "North Yorkshire",
})
end
+
+ describe "has the correct hidden_in_check_answers" do
+ context "when saledate.year before 2023" do
+ let(:log) { build(:lettings_log, startdate: Time.zone.parse("2022-07-01")) }
+
+ it "returns false" do
+ expect(question.hidden_in_check_answers?(log)).to eq(false)
+ end
+ end
+
+ context "when saledate.year >= 2023" do
+ let(:log) { build(:lettings_log, startdate: Time.zone.parse("2023-07-01")) }
+
+ it "returns true" do
+ expect(question.hidden_in_check_answers?(log)).to eq(false)
+ end
+ end
+
+ context "when saledate.year >= 2023 and la inferred" do
+ let(:log) { build(:lettings_log, startdate: Time.zone.parse("2023-07-01")) }
+
+ before do
+ allow(log).to receive(:is_la_inferred?).and_return(true)
+ end
+
+ it "returns true" do
+ expect(question.hidden_in_check_answers?(log)).to eq(true)
+ end
+ end
+ end
end
diff --git a/spec/models/form/lettings/questions/postcode_for_full_address_spec.rb b/spec/models/form/lettings/questions/postcode_for_full_address_spec.rb
new file mode 100644
index 000000000..ccb02ef07
--- /dev/null
+++ b/spec/models/form/lettings/questions/postcode_for_full_address_spec.rb
@@ -0,0 +1,62 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::PostcodeForFullAddress, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("postcode_full")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Postcode")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to be_nil
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct width" do
+ expect(question.width).to eq(5)
+ end
+
+ it "has the correct inferred_answers" do
+ expect(question.inferred_answers).to eq({
+ "la" => {
+ "is_la_inferred" => true,
+ },
+ })
+ end
+
+ it "has the correct inferred_check_answers_value" do
+ expect(question.inferred_check_answers_value).to eq([{
+ "condition" => {
+ "pcodenk" => 1,
+ },
+ "value" => "Not known",
+ }])
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers?).to eq(true)
+ end
+end
diff --git a/spec/models/form/lettings/questions/town_or_city_spec.rb b/spec/models/form/lettings/questions/town_or_city_spec.rb
new file mode 100644
index 000000000..8741fb058
--- /dev/null
+++ b/spec/models/form/lettings/questions/town_or_city_spec.rb
@@ -0,0 +1,49 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::TownOrCity, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("town_or_city")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Town or city")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to be_nil
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct inferred check answers value" do
+ expect(question.inferred_check_answers_value).to be_nil
+ end
+
+ it "has the correct check_answers_card_number" do
+ expect(question.check_answers_card_number).to be_nil
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers?).to eq(true)
+ end
+end
diff --git a/spec/models/form/lettings/questions/uprn_confirmation_spec.rb b/spec/models/form/lettings/questions/uprn_confirmation_spec.rb
new file mode 100644
index 000000000..3c409641d
--- /dev/null
+++ b/spec/models/form/lettings/questions/uprn_confirmation_spec.rb
@@ -0,0 +1,90 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::UprnConfirmation, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("uprn_confirmed")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Is this the property address?")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to eq("Is this the right address?")
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("radio")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to be_nil
+ end
+
+ it "has the correct unanswered_error_message" do
+ expect(question.unanswered_error_message).to eq("You must answer is this the right address?")
+ end
+
+ describe "notification_banner" do
+ context "when address is not present" do
+ it "returns nil" do
+ log = create(:lettings_log)
+
+ expect(question.notification_banner(log)).to be_nil
+ end
+ end
+
+ context "when address is present" do
+ it "returns formatted value" do
+ log = create(:lettings_log, address_line1: "1, Test Street", town_or_city: "Test Town", county: "Test County", postcode_full: "AA1 1AA", uprn: "1234")
+
+ expect(question.notification_banner(log)).to eq(
+ {
+ heading: "1, Test Street\nAA1 1AA\nTest Town\nTest County",
+ title: "UPRN: 1234",
+ },
+ )
+ end
+ end
+ end
+
+ describe "has the correct hidden_in_check_answers" do
+ context "when uprn_known != 1 && uprn_confirmed == nil" do
+ let(:log) { create(:lettings_log, uprn_known: 0, uprn_confirmed: nil) }
+
+ it "returns true" do
+ expect(question.hidden_in_check_answers?(log)).to eq(true)
+ end
+ end
+
+ context "when uprn_known == 1 && uprn_confirmed == nil" do
+ let(:log) { create(:lettings_log, uprn_known: 1, uprn_confirmed: nil) }
+
+ it "returns false" do
+ expect(question.hidden_in_check_answers?(log)).to eq(false)
+ end
+ end
+
+ context "when uprn_known != 1 && uprn_confirmed == 1" do
+ let(:log) { create(:lettings_log, uprn_known: 1, uprn_confirmed: 1) }
+
+ it "returns true" do
+ expect(question.hidden_in_check_answers?(log)).to eq(true)
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/questions/uprn_known_spec.rb b/spec/models/form/lettings/questions/uprn_known_spec.rb
new file mode 100644
index 000000000..1a0f810da
--- /dev/null
+++ b/spec/models/form/lettings/questions/uprn_known_spec.rb
@@ -0,0 +1,59 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::UprnKnown, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("uprn_known")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("Do you know the property UPRN?")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to eq("UPRN known?")
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("radio")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct answer_options" do
+ expect(question.answer_options).to eq({
+ "0" => { "value" => "No" },
+ "1" => { "value" => "Yes" },
+ })
+ end
+
+ it "has correct conditional for" do
+ expect(question.conditional_for).to be_nil
+ end
+
+ it "has the correct unanswered_error_message" do
+ expect(question.unanswered_error_message).to eq("You must answer UPRN known?")
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to eq(
+ "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.
+ You can continue without the UPRN, but it means we will need you to enter the address of the property.",
+ )
+ end
+
+ it "has the correct hidden_in_check_answers" do
+ expect(question.hidden_in_check_answers).to be_nil
+ end
+end
diff --git a/spec/models/form/lettings/questions/uprn_spec.rb b/spec/models/form/lettings/questions/uprn_spec.rb
new file mode 100644
index 000000000..8f6ba047a
--- /dev/null
+++ b/spec/models/form/lettings/questions/uprn_spec.rb
@@ -0,0 +1,92 @@
+require "rails_helper"
+
+RSpec.describe Form::Lettings::Questions::Uprn, type: :model do
+ subject(:question) { described_class.new(question_id, question_definition, page) }
+
+ let(:question_id) { nil }
+ let(:question_definition) { nil }
+ let(:page) { instance_double(Form::Page) }
+
+ it "has correct page" do
+ expect(question.page).to eq(page)
+ end
+
+ it "has the correct id" do
+ expect(question.id).to eq("uprn")
+ end
+
+ it "has the correct header" do
+ expect(question.header).to eq("What is the property's UPRN")
+ end
+
+ it "has the correct check_answer_label" do
+ expect(question.check_answer_label).to eq("UPRN")
+ end
+
+ it "has the correct type" do
+ expect(question.type).to eq("text")
+ end
+
+ it "is not marked as derived" do
+ expect(question.derived?).to be false
+ end
+
+ it "has the correct question_number" do
+ expect(question.question_number).to eq(11)
+ end
+
+ it "has the correct hint" do
+ expect(question.hint_text).to eq("The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.")
+ end
+
+ it "has the correct unanswered_error_message" do
+ expect(question.unanswered_error_message).to eq("UPRN must be 12 digits or less")
+ end
+
+ describe "get_extra_check_answer_value" do
+ context "when address is not present" do
+ let(:log) { create(:lettings_log) }
+
+ it "returns nil" do
+ expect(question.get_extra_check_answer_value(log)).to be_nil
+ end
+ end
+
+ context "when address is present" do
+ let(:log) do
+ create(
+ :lettings_log,
+ address_line1: "1, Test Street",
+ town_or_city: "Test Town",
+ county: "Test County",
+ postcode_full: "AA1 1AA",
+ la: "E09000003",
+ )
+ end
+
+ it "returns formatted value" do
+ expect(question.get_extra_check_answer_value(log)).to eq(
+ "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster",
+ )
+ end
+ end
+ end
+
+ describe "has the correct hidden_in_check_answers" do
+ context "when uprn_known == 1" do
+ let(:log) { create(:lettings_log, uprn_known: 1) }
+
+ it "returns false" do
+ expect(question.hidden_in_check_answers?(log)).to eq(false)
+ end
+ end
+
+ context "when uprn_known != 1" do
+ let(:log) { create(:lettings_log, uprn_known: 0) }
+
+ it "returns false" do
+ expect(question.hidden_in_check_answers?(log)).to eq(true)
+ end
+ end
+ end
+end
diff --git a/spec/models/form/lettings/subsections/property_information_spec.rb b/spec/models/form/lettings/subsections/property_information_spec.rb
index 8b30964c3..2e7e58deb 100644
--- a/spec/models/form/lettings/subsections/property_information_spec.rb
+++ b/spec/models/form/lettings/subsections/property_information_spec.rb
@@ -9,28 +9,67 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
expect(property_information.section).to eq(section)
end
- it "has correct pages" do
- expect(property_information.pages.map(&:id)).to eq(
- %w[
- property_postcode
- property_local_authority
- first_time_property_let_as_social_housing
- property_let_type
- property_vacancy_reason_not_first_let
- property_vacancy_reason_first_let
- property_number_of_times_relet_not_social_let
- property_number_of_times_relet_social_let
- property_unit_type
- property_building_type
- property_wheelchair_accessible
- property_number_of_bedrooms
- void_or_renewal_date
- void_date_value_check
- new_build_handover_date
- property_major_repairs
- property_major_repairs_value_check
- ],
- )
+ describe "pages" do
+ let(:section) { instance_double(Form::Sales::Sections::Household, form: instance_double(Form, start_date:)) }
+
+ context "when 2022" do
+ let(:start_date) { Time.utc(2022, 2, 8) }
+
+ it "has correct pages" do
+ expect(property_information.pages.compact.map(&:id)).to eq(
+ %w[
+ property_postcode
+ property_local_authority
+ first_time_property_let_as_social_housing
+ property_let_type
+ property_vacancy_reason_not_first_let
+ property_vacancy_reason_first_let
+ property_number_of_times_relet_not_social_let
+ property_number_of_times_relet_social_let
+ property_unit_type
+ property_building_type
+ property_wheelchair_accessible
+ property_number_of_bedrooms
+ void_or_renewal_date
+ void_date_value_check
+ new_build_handover_date
+ property_major_repairs
+ property_major_repairs_value_check
+ ],
+ )
+ end
+ end
+
+ context "when 2023" do
+ let(:start_date) { Time.utc(2023, 2, 8) }
+
+ it "has correct pages" do
+ expect(property_information.pages.map(&:id)).to eq(
+ %w[
+ uprn_known
+ uprn
+ uprn_confirmation
+ address
+ property_local_authority
+ first_time_property_let_as_social_housing
+ property_let_type
+ property_vacancy_reason_not_first_let
+ property_vacancy_reason_first_let
+ property_number_of_times_relet_not_social_let
+ property_number_of_times_relet_social_let
+ property_unit_type
+ property_building_type
+ property_wheelchair_accessible
+ property_number_of_bedrooms
+ void_or_renewal_date
+ void_date_value_check
+ new_build_handover_date
+ property_major_repairs
+ property_major_repairs_value_check
+ ],
+ )
+ end
+ end
end
it "has the correct id" do
diff --git a/spec/models/form/sales/questions/address_line1_spec.rb b/spec/models/form/sales/questions/address_line1_spec.rb
index bc65c0646..27c0179e2 100644
--- a/spec/models/form/sales/questions/address_line1_spec.rb
+++ b/spec/models/form/sales/questions/address_line1_spec.rb
@@ -11,6 +11,10 @@ RSpec.describe Form::Sales::Questions::AddressLine1, type: :model do
expect(question.page).to eq(page)
end
+ it "has the correct question_number" do
+ expect(question.question_number).to eq(15)
+ end
+
it "has the correct id" do
expect(question.id).to eq("address_line1")
end
diff --git a/spec/models/form/sales/questions/uprn_spec.rb b/spec/models/form/sales/questions/uprn_spec.rb
index 2f42c1cdd..50e575445 100644
--- a/spec/models/form/sales/questions/uprn_spec.rb
+++ b/spec/models/form/sales/questions/uprn_spec.rb
@@ -31,6 +31,10 @@ RSpec.describe Form::Sales::Questions::Uprn, type: :model do
expect(question.derived?).to be false
end
+ it "has the correct question_number" do
+ expect(question.question_number).to eq(14)
+ end
+
it "has the correct hint" do
expect(question.hint_text).to eq("The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.")
end
diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb
index 43cbc69ce..9a8666eea 100644
--- a/spec/models/lettings_log_spec.rb
+++ b/spec/models/lettings_log_spec.rb
@@ -1,6 +1,7 @@
require "rails_helper"
require "shared/shared_examples_for_derived_fields"
+# rubocop:disable RSpec/AnyInstance
RSpec.describe LettingsLog do
let(:different_managing_organisation) { create(:organisation) }
let(:created_by_user) { create(:user) }
@@ -3010,4 +3011,60 @@ RSpec.describe LettingsLog do
end
end
end
+
+ describe "#process_uprn_change!" do
+ context "when UPRN set to a value" do
+ let(:lettings_log) do
+ create(
+ :lettings_log,
+ uprn: "123456789",
+ uprn_confirmed: 1,
+ county: "county",
+ )
+ end
+
+ it "updates sales log fields" do
+ lettings_log.uprn = "1111111"
+
+ allow_any_instance_of(UprnClient).to receive(:call)
+ allow_any_instance_of(UprnClient).to receive(:result).and_return({
+ "UPRN" => "UPRN",
+ "UDPRN" => "UDPRN",
+ "ADDRESS" => "full address",
+ "SUB_BUILDING_NAME" => "0",
+ "BUILDING_NAME" => "building name",
+ "THOROUGHFARE_NAME" => "thoroughfare",
+ "POST_TOWN" => "posttown",
+ "POSTCODE" => "postcode",
+ })
+
+ expect { lettings_log.process_uprn_change! }.to change(lettings_log, :address_line1).from(nil).to("0, Building Name, Thoroughfare")
+ .and change(lettings_log, :town_or_city).from(nil).to("Posttown")
+ .and change(lettings_log, :postcode_full).from(nil).to("POSTCODE")
+ .and change(lettings_log, :uprn_confirmed).from(1).to(nil)
+ .and change(lettings_log, :county).from("county").to(nil)
+ end
+ end
+
+ context "when UPRN nil" do
+ let(:lettings_log) { create(:lettings_log, uprn: nil) }
+
+ it "does not update sales log" do
+ expect { lettings_log.process_uprn_change! }.not_to change(lettings_log, :attributes)
+ end
+ end
+
+ context "when service errors" do
+ let(:lettings_log) { create(:lettings_log, uprn: "123456789", uprn_confirmed: 1) }
+ let(:error_message) { "error" }
+
+ it "adds error to sales log" do
+ allow_any_instance_of(UprnClient).to receive(:call)
+ allow_any_instance_of(UprnClient).to receive(:error).and_return(error_message)
+
+ expect { lettings_log.process_uprn_change! }.to change { lettings_log.errors[:uprn] }.from([]).to([error_message])
+ end
+ end
+ end
end
+# rubocop:enable RSpec/AnyInstance
diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb
index 231dc68c4..4bc90da37 100644
--- a/spec/models/sales_log_spec.rb
+++ b/spec/models/sales_log_spec.rb
@@ -517,7 +517,14 @@ RSpec.describe SalesLog, type: :model do
describe "#process_uprn_change!" do
context "when UPRN set to a value" do
- let(:sales_log) { create(:sales_log, uprn: "123456789", uprn_confirmed: 1) }
+ let(:sales_log) do
+ create(
+ :sales_log,
+ uprn: "123456789",
+ uprn_confirmed: 1,
+ county: "county",
+ )
+ end
it "updates sales log fields" do
sales_log.uprn = "1111111"
@@ -538,6 +545,7 @@ RSpec.describe SalesLog, type: :model do
.and change(sales_log, :town_or_city).from(nil).to("Posttown")
.and change(sales_log, :postcode_full).from(nil).to("POSTCODE")
.and change(sales_log, :uprn_confirmed).from(1).to(nil)
+ .and change(sales_log, :county).from("county").to(nil)
end
end
From 3cb67623ac856c04aac9ccb104822fe10a7d44c2 Mon Sep 17 00:00:00 2001
From: James Rose
Date: Wed, 22 Mar 2023 13:08:50 +0000
Subject: [PATCH 12/31] Update collection year end dates for 2022 onwards
(#1453)
This fixes a mistake I made in https://github.com/communitiesuk/submit-social-housing-lettings-and-sales-data/pull/1312 where I set the dates to July instead of June.
---
app/models/form.rb | 4 ++--
config/forms/2022_2023.json | 2 +-
spec/helpers/tasklist_helper_spec.rb | 4 ++--
spec/models/form_spec.rb | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/app/models/form.rb b/app/models/form.rb
index 9fa908427..8f9dc47f9 100644
--- a/app/models/form.rb
+++ b/app/models/form.rb
@@ -7,9 +7,9 @@ class Form
if sales_or_start_year_after_2022?(type, start_year)
@start_date = Time.zone.local(start_year, 4, 1)
@end_date = if start_year && start_year.to_i > 2022
- Time.zone.local(start_year + 1, 7, 9)
+ Time.zone.local(start_year + 1, 6, 9)
else
- Time.zone.local(start_year + 1, 7, 7)
+ Time.zone.local(start_year + 1, 6, 7)
end
@setup_sections = type == "sales" ? [Form::Sales::Sections::Setup.new(nil, nil, self)] : [Form::Lettings::Sections::Setup.new(nil, nil, self)]
@form_sections = sections_in_form.map { |sec| sec.new(nil, nil, self) }
diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json
index 6a1b8cc40..3162a2b36 100644
--- a/config/forms/2022_2023.json
+++ b/config/forms/2022_2023.json
@@ -1,7 +1,7 @@
{
"form_type": "lettings",
"start_date": "2022-04-01T00:00:00.000+01:00",
- "end_date": "2023-07-09T00:00:00.000+01:00",
+ "end_date": "2023-06-09T00:00:00.000+01:00",
"unresolved_log_redirect_page_id": "tenancy_start_date",
"sections": {
"tenancy_and_property": {
diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb
index 5d75616ec..b4e26437b 100644
--- a/spec/helpers/tasklist_helper_spec.rb
+++ b/spec/helpers/tasklist_helper_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe TasklistHelper do
it "returns relevant text" do
expect(review_log_text(sales_log)).to eq(
- "You can #{govuk_link_to 'review and make changes to this log', review_sales_log_path(id: sales_log, sales_log: true)} until 7 July 2023.".html_safe,
+ "You can #{govuk_link_to 'review and make changes to this log', review_sales_log_path(id: sales_log, sales_log: true)} until 7 June 2023.".html_safe,
)
end
end
@@ -121,7 +121,7 @@ RSpec.describe TasklistHelper do
it "returns relevant text" do
expect(review_log_text(lettings_log)).to eq(
- "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 9 July 2024.".html_safe,
+ "You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(lettings_log)} until 9 June 2024.".html_safe,
)
end
end
diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb
index 3236623c1..a1cf650c0 100644
--- a/spec/models/form_spec.rb
+++ b/spec/models/form_spec.rb
@@ -252,7 +252,7 @@ RSpec.describe Form, type: :model do
expect(form.questions.count).to eq(17)
expect(form.questions.first.id).to eq("owning_organisation_id")
expect(form.start_date).to eq(Time.zone.parse("2022-04-01"))
- expect(form.end_date).to eq(Time.zone.parse("2023-07-07"))
+ expect(form.end_date).to eq(Time.zone.parse("2023-06-07"))
expect(form.unresolved_log_redirect_page_id).to eq(nil)
end
From 2edb63d59337b3fcbe583081d09cf987a513a822 Mon Sep 17 00:00:00 2001
From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com>
Date: Wed, 22 Mar 2023 16:05:27 +0000
Subject: [PATCH 13/31] CLDC-2148-household-count-validation (#1452)
* alter har dmax value for number of other people in the property, change a couple of depends on formulations to improve readability
* correct linting error
---
.../form/sales/pages/number_of_others_in_property.rb | 6 +++---
.../sales/questions/number_of_others_in_property.rb | 4 ++--
.../sales/pages/number_of_others_in_property_spec.rb | 12 ++++++------
.../questions/number_of_others_in_property_spec.rb | 12 ++++++------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/app/models/form/sales/pages/number_of_others_in_property.rb b/app/models/form/sales/pages/number_of_others_in_property.rb
index ebf9817bd..4c6b9e621 100644
--- a/app/models/form/sales/pages/number_of_others_in_property.rb
+++ b/app/models/form/sales/pages/number_of_others_in_property.rb
@@ -4,11 +4,11 @@ class Form::Sales::Pages::NumberOfOthersInProperty < ::Form::Page
@depends_on = [
{
"privacynotice" => 1,
- "jointpur" => joint_purchase ? 1 : 2,
+ "joint_purchase?" => joint_purchase,
},
{
- "noint" => 1,
- "jointpur" => joint_purchase ? 1 : 2,
+ "buyer_not_interviewed?" => true,
+ "joint_purchase?" => joint_purchase,
},
]
@joint_purchase = joint_purchase
diff --git a/app/models/form/sales/questions/number_of_others_in_property.rb b/app/models/form/sales/questions/number_of_others_in_property.rb
index 44e7e5563..556ddf837 100644
--- a/app/models/form/sales/questions/number_of_others_in_property.rb
+++ b/app/models/form/sales/questions/number_of_others_in_property.rb
@@ -3,12 +3,12 @@ class Form::Sales::Questions::NumberOfOthersInProperty < ::Form::Question
super(id, hsh, page)
@id = "hholdcount"
@check_answer_label = "Number of other people living in the property"
- @header = "Besides the buyer(s), how many other people live or will live in the property?"
+ @header = "Besides the #{'buyer'.pluralize(joint_purchase ? 2 : 1)}, how many other people live or will live in the property?"
@type = "numeric"
@hint_text = hint(joint_purchase)
@width = 2
@min = 0
- @max = joint_purchase ? 4 : 5
+ @max = 15
@question_number = 35
end
diff --git a/spec/models/form/sales/pages/number_of_others_in_property_spec.rb b/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
index 3503a1b9f..9a0adaafb 100644
--- a/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
+++ b/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
@@ -32,11 +32,11 @@ RSpec.describe Form::Sales::Pages::NumberOfOthersInProperty, type: :model do
expect(page.depends_on).to eq([
{
"privacynotice" => 1,
- "jointpur" => 2,
+ "joint_purchase?" => joint_purchase,
},
{
- "noint" => 1,
- "jointpur" => 2,
+ "buyer_not_interviewed?" => true,
+ "joint_purchase?" => joint_purchase,
},
])
end
@@ -53,11 +53,11 @@ RSpec.describe Form::Sales::Pages::NumberOfOthersInProperty, type: :model do
expect(page.depends_on).to eq([
{
"privacynotice" => 1,
- "jointpur" => 1,
+ "joint_purchase?" => joint_purchase,
},
{
- "noint" => 1,
- "jointpur" => 1,
+ "buyer_not_interviewed?" => true,
+ "joint_purchase?" => joint_purchase,
},
])
end
diff --git a/spec/models/form/sales/questions/number_of_others_in_property_spec.rb b/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
index 2bb50f80b..3d6e9d9c5 100644
--- a/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
+++ b/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
let(:joint_purchase) { true }
it "has correct page" do
- expect(question.page).to eq(page)
+ expect(question.page).to be(page)
end
it "has the correct id" do
@@ -17,7 +17,7 @@ RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("Besides the buyer(s), how many other people live or will live in the property?")
+ expect(question.header).to eq("Besides the buyers, how many other people live or will live in the property?")
end
it "has the correct check_answer_label" do
@@ -37,11 +37,11 @@ RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
end
it "has the correct min" do
- expect(question.min).to eq(0)
+ expect(question.min).to be 0
end
it "has the correct max" do
- expect(question.max).to eq(4)
+ expect(question.max).to be 15
end
context "with non joint purchase" do
@@ -51,8 +51,8 @@ RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
expect(question.hint_text).to eq("You can provide details for a maximum of 5 other people if there is only one buyer.")
end
- it "has the correct max" do
- expect(question.max).to eq(5)
+ it "has the correct header" do
+ expect(question.header).to eq("Besides the buyer, how many other people live or will live in the property?")
end
end
end
From 97bbf1924d306b8aa459262e046b3e4e2ddf9ac3 Mon Sep 17 00:00:00 2001
From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com>
Date: Wed, 22 Mar 2023 16:05:46 +0000
Subject: [PATCH 14/31] CLDC-2016 mortgage validation (#1445)
* add method to sales log and use in depends on to increase readability
* increase minimum allowed value for mortgage
* write tests and add validation error to config for new validation
* write validation
* adjust validation so it doesn't trigger when mortgage value is derived as 0
* correct linting problem and update tests to account for change in validation
---
app/models/form/sales/pages/mortgage_amount.rb | 4 +---
.../form/sales/questions/mortgage_amount.rb | 2 +-
app/models/sales_log.rb | 4 ++++
.../validations/sales/financial_validations.rb | 4 ++++
config/locales/en.yml | 1 +
.../form/sales/pages/mortgage_amount_spec.rb | 4 +---
.../sales/questions/mortgage_amount_spec.rb | 6 +++---
.../sales/financial_validations_spec.rb | 18 ++++++++++++++++++
8 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/app/models/form/sales/pages/mortgage_amount.rb b/app/models/form/sales/pages/mortgage_amount.rb
index 793570b46..73e306c2a 100644
--- a/app/models/form/sales/pages/mortgage_amount.rb
+++ b/app/models/form/sales/pages/mortgage_amount.rb
@@ -3,9 +3,7 @@ class Form::Sales::Pages::MortgageAmount < ::Form::Page
super(id, hsh, subsection)
@ownershipsch = ownershipsch
@header = "Mortgage Amount"
- @depends_on = [{
- "mortgageused" => 1,
- }]
+ @depends_on = [{ "mortgage_used?" => true }]
end
def questions
diff --git a/app/models/form/sales/questions/mortgage_amount.rb b/app/models/form/sales/questions/mortgage_amount.rb
index 12959709a..9b199b2aa 100644
--- a/app/models/form/sales/questions/mortgage_amount.rb
+++ b/app/models/form/sales/questions/mortgage_amount.rb
@@ -5,7 +5,7 @@ class Form::Sales::Questions::MortgageAmount < ::Form::Question
@check_answer_label = "Mortgage amount"
@header = "What is the mortgage amount?"
@type = "numeric"
- @min = 0
+ @min = 1
@width = 5
@prefix = "£"
@hint_text = "Enter the amount of mortgage agreed with the mortgage lender. Exclude any deposits or cash payments. Numeric in pounds. Rounded to the nearest pound."
diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb
index ba2ea4fa8..2a6e1a6d3 100644
--- a/app/models/sales_log.rb
+++ b/app/models/sales_log.rb
@@ -243,6 +243,10 @@ class SalesLog < Log
ownershipsch == 2
end
+ def mortgage_used?
+ mortgageused == 1
+ end
+
def mortgage_not_used?
mortgageused == 2
end
diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb
index faf436afa..61772be93 100644
--- a/app/models/validations/sales/financial_validations.rb
+++ b/app/models/validations/sales/financial_validations.rb
@@ -36,6 +36,10 @@ module Validations::Sales::FinancialValidations
end
end
+ def validate_mortgage(record)
+ record.errors.add :mortgage, I18n.t("validations.financial.mortgage") if record.mortgage_used? && record.mortgage&.zero?
+ end
+
def validate_cash_discount(record)
return unless record.cashdis
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 36d8b93f8..56caa6a59 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -316,6 +316,7 @@ en:
equity:
under_min: "The minimum initial equity stake for this type of shared ownership sale is %{min_equity}%"
over_max: "The maximum initial equity stake is %{max_equity}%"
+ mortgage: "Mortgage value cannot be £0 if a mortgage was used for the purchase of this property"
household:
reasonpref:
diff --git a/spec/models/form/sales/pages/mortgage_amount_spec.rb b/spec/models/form/sales/pages/mortgage_amount_spec.rb
index 551788fbb..c6f6f924e 100644
--- a/spec/models/form/sales/pages/mortgage_amount_spec.rb
+++ b/spec/models/form/sales/pages/mortgage_amount_spec.rb
@@ -28,8 +28,6 @@ RSpec.describe Form::Sales::Pages::MortgageAmount, type: :model do
end
it "has correct depends_on" do
- expect(page.depends_on).to eq([{
- "mortgageused" => 1,
- }])
+ expect(page.depends_on).to eq([{ "mortgage_used?" => true }])
end
end
diff --git a/spec/models/form/sales/questions/mortgage_amount_spec.rb b/spec/models/form/sales/questions/mortgage_amount_spec.rb
index 328406ecd..758101867 100644
--- a/spec/models/form/sales/questions/mortgage_amount_spec.rb
+++ b/spec/models/form/sales/questions/mortgage_amount_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Form::Sales::Questions::MortgageAmount, type: :model do
let(:page) { instance_double(Form::Page) }
it "has correct page" do
- expect(question.page).to eq(page)
+ expect(question.page).to be(page)
end
it "has the correct id" do
@@ -36,7 +36,7 @@ RSpec.describe Form::Sales::Questions::MortgageAmount, type: :model do
end
it "has correct width" do
- expect(question.width).to eq(5)
+ expect(question.width).to be(5)
end
it "has correct prefix" do
@@ -44,6 +44,6 @@ RSpec.describe Form::Sales::Questions::MortgageAmount, type: :model do
end
it "has correct min" do
- expect(question.min).to eq(0)
+ expect(question.min).to be(1)
end
end
diff --git a/spec/models/validations/sales/financial_validations_spec.rb b/spec/models/validations/sales/financial_validations_spec.rb
index b60ef5e6a..e1eb81dea 100644
--- a/spec/models/validations/sales/financial_validations_spec.rb
+++ b/spec/models/validations/sales/financial_validations_spec.rb
@@ -113,6 +113,24 @@ RSpec.describe Validations::Sales::FinancialValidations do
end
end
+ describe "#validate_mortgage" do
+ let(:record) { FactoryBot.create(:sales_log) }
+
+ it "adds an error is the mortgage is zero" do
+ record.mortgageused = 1
+ record.mortgage = 0
+ financial_validator.validate_mortgage(record)
+ expect(record.errors[:mortgage]).to include I18n.t("validations.financial.mortgage")
+ end
+
+ it "does not add an error is the mortgage is positive" do
+ record.mortgageused = 1
+ record.mortgage = 234
+ financial_validator.validate_mortgage(record)
+ expect(record.errors).to be_empty
+ end
+ end
+
describe "#validate_cash_discount" do
let(:record) { FactoryBot.create(:sales_log) }
From ffcfa7db6eac61fca55a65fca5475c7b58be204f Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Thu, 23 Mar 2023 09:41:09 +0000
Subject: [PATCH 15/31] bulk upload age can be null (#1459)
---
.../lettings/year2022/row_parser.rb | 30 +++++++++----------
.../lettings/year2023/row_parser.rb | 30 +++++++++----------
.../lettings/year2022/row_parser_spec.rb | 12 ++++++++
.../lettings/year2023/row_parser_spec.rb | 12 ++++++++
4 files changed, 54 insertions(+), 30 deletions(-)
diff --git a/app/services/bulk_upload/lettings/year2022/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb
index 560ed82b5..b2bc24110 100644
--- a/app/services/bulk_upload/lettings/year2022/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb
@@ -282,13 +282,13 @@ class BulkUpload::Lettings::Year2022::RowParser
validates :field_4, presence: { if: proc { [2, 4, 6, 8, 10, 12].include?(field_1) } }
validates :field_12, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 1 must be a number or the letter R" }
- validates :field_13, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 2 must be a number or the letter R" }
- validates :field_14, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 3 must be a number or the letter R" }
- validates :field_15, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 4 must be a number or the letter R" }
- validates :field_16, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 5 must be a number or the letter R" }
- validates :field_17, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 6 must be a number or the letter R" }
- validates :field_18, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" }
- validates :field_19, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" }
+ validates :field_13, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 2 must be a number or the letter R" }, allow_blank: true
+ validates :field_14, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 3 must be a number or the letter R" }, allow_blank: true
+ validates :field_15, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 4 must be a number or the letter R" }, allow_blank: true
+ validates :field_16, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 5 must be a number or the letter R" }, allow_blank: true
+ validates :field_17, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 6 must be a number or the letter R" }, allow_blank: true
+ validates :field_18, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" }, allow_blank: true
+ validates :field_19, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" }, allow_blank: true
validates :field_96, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (day)") }
validates :field_97, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (month)") }
@@ -848,28 +848,28 @@ private
attributes["tenancylength"] = field_11
attributes["declaration"] = field_132
- attributes["age1_known"] = field_12 == "R" ? 1 : 0
+ attributes["age1_known"] = (field_12 == "R" || field_12.blank? ? 1 : 0)
attributes["age1"] = field_12 if attributes["age1_known"].zero? && field_12&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age2_known"] = field_13 == "R" ? 1 : 0
+ attributes["age2_known"] = (field_13 == "R" || field_13.blank? ? 1 : 0)
attributes["age2"] = field_13 if attributes["age2_known"].zero? && field_13&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age3_known"] = field_14 == "R" ? 1 : 0
+ attributes["age3_known"] = (field_14 == "R" || field_14.blank? ? 1 : 0)
attributes["age3"] = field_14 if attributes["age3_known"].zero? && field_14&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age4_known"] = field_15 == "R" ? 1 : 0
+ attributes["age4_known"] = (field_15 == "R" || field_15.blank? ? 1 : 0)
attributes["age4"] = field_15 if attributes["age4_known"].zero? && field_15&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age5_known"] = field_16 == "R" ? 1 : 0
+ attributes["age5_known"] = (field_16 == "R" || field_16.blank? ? 1 : 0)
attributes["age5"] = field_16 if attributes["age5_known"].zero? && field_16&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age6_known"] = field_17 == "R" ? 1 : 0
+ attributes["age6_known"] = (field_17 == "R" || field_17.blank? ? 1 : 0)
attributes["age6"] = field_17 if attributes["age6_known"].zero? && field_17&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age7_known"] = field_18 == "R" ? 1 : 0
+ attributes["age7_known"] = (field_18 == "R" || field_18.blank? ? 1 : 0)
attributes["age7"] = field_18 if attributes["age7_known"].zero? && field_18&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age8_known"] = field_19 == "R" ? 1 : 0
+ attributes["age8_known"] = (field_19 == "R" || field_19.blank? ? 1 : 0)
attributes["age8"] = field_19 if attributes["age8_known"].zero? && field_19&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_20
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index 724b1c2ef..69dc6aeca 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -284,13 +284,13 @@ class BulkUpload::Lettings::Year2023::RowParser
validates :field_16, presence: { if: proc { [2, 4, 6, 8, 10, 12].include?(field_5) } }
validates :field_46, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 1 must be a number or the letter R" }
- validates :field_52, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 2 must be a number or the letter R" }
- validates :field_56, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 3 must be a number or the letter R" }
- validates :field_60, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 4 must be a number or the letter R" }
- validates :field_64, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 5 must be a number or the letter R" }
- validates :field_68, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 6 must be a number or the letter R" }
- validates :field_72, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" }
- validates :field_76, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" }
+ validates :field_52, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 2 must be a number or the letter R" }, allow_blank: true
+ validates :field_56, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 3 must be a number or the letter R" }, allow_blank: true
+ validates :field_60, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 4 must be a number or the letter R" }, allow_blank: true
+ validates :field_64, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 5 must be a number or the letter R" }, allow_blank: true
+ validates :field_68, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 6 must be a number or the letter R" }, allow_blank: true
+ validates :field_72, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" }, allow_blank: true
+ validates :field_76, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" }, allow_blank: true
validates :field_7, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (day)") }
validates :field_8, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (month)") }
@@ -790,28 +790,28 @@ private
attributes["tenancylength"] = field_43
attributes["declaration"] = field_45
- attributes["age1_known"] = field_46 == "R" ? 1 : 0
+ attributes["age1_known"] = (field_46 == "R" || field_46.blank? ? 1 : 0)
attributes["age1"] = field_46 if attributes["age1_known"].zero? && field_46&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age2_known"] = field_52 == "R" ? 1 : 0
+ attributes["age2_known"] = (field_52 == "R" || field_52.blank? ? 1 : 0)
attributes["age2"] = field_52 if attributes["age2_known"].zero? && field_52&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age3_known"] = field_56 == "R" ? 1 : 0
+ attributes["age3_known"] = (field_56 == "R" || field_56.blank? ? 1 : 0)
attributes["age3"] = field_56 if attributes["age3_known"].zero? && field_56&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age4_known"] = field_60 == "R" ? 1 : 0
+ attributes["age4_known"] = (field_60 == "R" || field_60.blank? ? 1 : 0)
attributes["age4"] = field_60 if attributes["age4_known"].zero? && field_60&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age5_known"] = field_64 == "R" ? 1 : 0
+ attributes["age5_known"] = (field_64 == "R" || field_64.blank? ? 1 : 0)
attributes["age5"] = field_64 if attributes["age5_known"].zero? && field_64&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age6_known"] = field_68 == "R" ? 1 : 0
+ attributes["age6_known"] = (field_68 == "R" || field_68.blank? ? 1 : 0)
attributes["age6"] = field_68 if attributes["age6_known"].zero? && field_68&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age7_known"] = field_72 == "R" ? 1 : 0
+ attributes["age7_known"] = (field_72 == "R" || field_72.blank? ? 1 : 0)
attributes["age7"] = field_72 if attributes["age7_known"].zero? && field_72&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age8_known"] = field_76 == "R" ? 1 : 0
+ attributes["age8_known"] = (field_76 == "R" || field_76.blank? ? 1 : 0)
attributes["age8"] = field_76 if attributes["age8_known"].zero? && field_76&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_47
diff --git a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
index f03ea894b..f7848f690 100644
--- a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
@@ -742,6 +742,18 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
%w[age8_known age8 field_19],
].each do |known, age, field|
describe "##{known} and ##{age}" do
+ context "when #{field} is blank" do
+ let(:attributes) { { bulk_upload:, field.to_s => nil } }
+
+ it "sets ##{known} 1" do
+ expect(parser.log.public_send(known)).to be(1)
+ end
+
+ it "sets ##{age} to nil" do
+ expect(parser.log.public_send(age)).to be_nil
+ end
+ end
+
context "when #{field} is R" do
let(:attributes) { { bulk_upload:, field.to_s => "R" } }
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 80df8f54f..53cd24ed8 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -700,6 +700,18 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
%w[age8_known age8 field_76],
].each do |known, age, field|
describe "##{known} and ##{age}" do
+ context "when #{field} is blank" do
+ let(:attributes) { { bulk_upload:, field.to_s => nil } }
+
+ it "sets ##{known} 1" do
+ expect(parser.log.public_send(known)).to be(1)
+ end
+
+ it "sets ##{age} to nil" do
+ expect(parser.log.public_send(age)).to be_nil
+ end
+ end
+
context "when #{field} is R" do
let(:attributes) { { bulk_upload:, field.to_s => "R" } }
From 5c20a46a1b2144e438b181bc4eca00dae2a523d8 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Thu, 23 Mar 2023 13:01:25 +0000
Subject: [PATCH 16/31] CLDC-2143 Resolve more import validations (#1454)
* Remove failing equity over max on import
* Remove failing equity under min on import
* Use LA instead of postcode if postcode is in invalid format
* Do not backfill information about people indexed 7 and higher
* Unskip test
---
.../sales/financial_validations.rb | 4 +-
app/models/validations/shared_validations.rb | 2 +-
.../imports/sales_logs_import_service.rb | 13 ++-
.../imports/sales_logs_import_service_spec.rb | 91 ++++++++++++++++++-
4 files changed, 105 insertions(+), 5 deletions(-)
diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb
index 61772be93..8f81aa117 100644
--- a/app/models/validations/sales/financial_validations.rb
+++ b/app/models/validations/sales/financial_validations.rb
@@ -98,10 +98,10 @@ module Validations::Sales::FinancialValidations
if record.equity < range.min
record.errors.add :type, I18n.t("validations.financial.equity.under_min", min_equity: range.min)
- record.errors.add :equity, I18n.t("validations.financial.equity.under_min", min_equity: range.min)
+ record.errors.add :equity, :under_min, message: I18n.t("validations.financial.equity.under_min", min_equity: range.min)
elsif record.equity > range.max
record.errors.add :type, I18n.t("validations.financial.equity.over_max", max_equity: range.max)
- record.errors.add :equity, I18n.t("validations.financial.equity.over_max", max_equity: range.max)
+ record.errors.add :equity, :over_max, message: I18n.t("validations.financial.equity.over_max", max_equity: range.max)
end
end
diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb
index 32a8b22bd..e0f93515c 100644
--- a/app/models/validations/shared_validations.rb
+++ b/app/models/validations/shared_validations.rb
@@ -38,7 +38,7 @@ module Validations::SharedValidations
postcode = record.postcode_full
if record.postcode_known? && (postcode.blank? || !postcode.match(POSTCODE_REGEXP))
error_message = I18n.t("validations.postcode")
- record.errors.add :postcode_full, error_message
+ record.errors.add :postcode_full, :wrong_format, message: error_message
end
end
diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb
index c2844e019..e6f735b3e 100644
--- a/app/services/imports/sales_logs_import_service.rb
+++ b/app/services/imports/sales_logs_import_service.rb
@@ -214,6 +214,17 @@ module Imports
@logs_overridden << sales_log.old_id
attributes.delete("income1")
save_sales_log(attributes, previous_status)
+ elsif sales_log.errors.of_kind?(:equity, :over_max) || sales_log.errors.of_kind?(:equity, :under_min)
+ @logger.warn("Log #{sales_log.old_id}: Removing equity as the equity is invalid")
+ @logs_overridden << sales_log.old_id
+ attributes.delete("equity")
+ save_sales_log(attributes, previous_status)
+ elsif sales_log.errors.of_kind?(:postcode_full, :wrong_format)
+ @logger.warn("Log #{sales_log.old_id}: Removing postcode as the postcode is invalid")
+ @logs_overridden << sales_log.old_id
+ attributes.delete("postcode_full")
+ attributes["pcodenk"] = attributes["la"].present? ? 1 : nil
+ save_sales_log(attributes, previous_status)
else
@logger.error("Log #{sales_log.old_id}: Failed to import")
sales_log.errors.each do |error|
@@ -544,7 +555,7 @@ module Imports
end
# other household members characteristics
- (2..attributes["hhmemb"]).each do |index|
+ (2..[attributes["hhmemb"], 6].min).each do |index|
attributes["age#{index}_known"] ||= 1
attributes["sex#{index}"] ||= "R"
attributes["ecstat#{index}"] ||= 10
diff --git a/spec/services/imports/sales_logs_import_service_spec.rb b/spec/services/imports/sales_logs_import_service_spec.rb
index e41ffabaf..f0168ba11 100644
--- a/spec/services/imports/sales_logs_import_service_spec.rb
+++ b/spec/services/imports/sales_logs_import_service_spec.rb
@@ -439,6 +439,81 @@ RSpec.describe Imports::SalesLogsImportService do
end
end
+ context "and it has a record with invalid equity" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:Q23Equity").content = "78"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Log shared_ownership_sales_log: Removing equity as the equity is invalid/)
+ expect { sales_log_service.send(:create_log, sales_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ sales_log_service.send(:create_log, sales_log_xml)
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+
+ expect(sales_log).not_to be_nil
+ expect(sales_log.equity).to be_nil
+ end
+ end
+
+ context "and it has a record with invalid equity (under_min)" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:Q23Equity").content = "20"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Log shared_ownership_sales_log: Removing equity as the equity is invalid/)
+ expect { sales_log_service.send(:create_log, sales_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ sales_log_service.send(:create_log, sales_log_xml)
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+
+ expect(sales_log).not_to be_nil
+ expect(sales_log.equity).to be_nil
+ end
+ end
+
+ context "and it has a record with postcode in invalid format" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:Q14Postcode").content = "L3132AF"
+ sales_log_xml.at_xpath("//xmlns:Q14ONSLACode").content = "E07000223"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Log shared_ownership_sales_log: Removing postcode as the postcode is invalid/)
+ expect { sales_log_service.send(:create_log, sales_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers and sets correct la" do
+ allow(logger).to receive(:warn)
+
+ sales_log_service.send(:create_log, sales_log_xml)
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+
+ expect(sales_log).not_to be_nil
+ expect(sales_log.postcode_full).to be_nil
+ expect(sales_log.pcodenk).to eq(1) # not known
+ expect(sales_log.la).to eq("E07000223") # not known
+ end
+ end
+
context "and setup field has validation error in incomplete log" do
let(:sales_log_id) { "shared_ownership_sales_log" }
@@ -501,7 +576,7 @@ RSpec.describe Imports::SalesLogsImportService do
end
it "intercepts the relevant validation error" do
- expect(logger).to receive(:warn).with(/Enter a postcode in the correct format, for example AA1 1AA/)
+ expect(logger).to receive(:warn).with(/Removing field postcode_full from log triggering validation: wrong_format/)
expect { sales_log_service.send(:create_log, sales_log_xml) }
.not_to raise_error
end
@@ -518,6 +593,20 @@ RSpec.describe Imports::SalesLogsImportService do
end
end
+ context "when there is information about 7 people" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ sales_log_xml.at_xpath("//xmlns:P7Age").content = "22"
+ sales_log_xml.at_xpath("//xmlns:LiveInOther").content = "10"
+ end
+
+ it "does not try to save information about person 7" do
+ expect { sales_log_service.send(:create_log, sales_log_xml) }
+ .not_to raise_error
+ end
+ end
+
context "and it has an invalid record with invalid contracts exchange date" do
let(:sales_log_id) { "shared_ownership_sales_log" }
From 0b973ceebdc1c5177e2a6d249ff95137f14cc754 Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Thu, 23 Mar 2023 13:09:46 +0000
Subject: [PATCH 17/31] add new uprn and address fields to bulk upload (#1462)
---
.../lettings/year2023/row_parser.rb | 7 +++
.../lettings/year2023/row_parser_spec.rb | 63 +++++++++++++++++++
spec/support/bulk_upload/log_to_csv.rb | 10 +--
3 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index 69dc6aeca..e4ba7cb82 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -939,6 +939,13 @@ private
attributes["first_time_property_let_as_social_housing"] = first_time_property_let_as_social_housing
+ attributes["uprn_known"] = field_18.present? ? 1 : 0
+ attributes["uprn"] = field_18
+ attributes["address_line1"] = field_19
+ attributes["address_line2"] = field_20
+ attributes["town_or_city"] = field_21
+ attributes["county"] = field_22
+
attributes
end
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 53cd24ed8..997624757 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -63,6 +63,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {})
+ stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=100023336956")
+ .to_return(status: 200, body: "{}", headers: {})
+
parser.valid?
end
@@ -198,6 +201,8 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
field_35: now.strftime("%g"),
field_4: "1",
+
+ field_18: "100023336956",
}
end
@@ -689,6 +694,64 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
describe "#log" do
+ describe "#uprn" do
+ let(:attributes) { { bulk_upload:, field_18: "100023336956" } }
+
+ it "sets to given value" do
+ expect(parser.log.uprn).to eql("100023336956")
+ end
+ end
+
+ describe "#uprn_known" do
+ context "when uprn specified" do
+ let(:attributes) { { bulk_upload:, field_18: "100023336956" } }
+
+ it "sets to 1" do
+ expect(parser.log.uprn_known).to be(1)
+ end
+ end
+
+ context "when uprn blank" do
+ let(:attributes) { { bulk_upload:, field_18: "" } }
+
+ it "sets to 0" do
+ expect(parser.log.uprn_known).to be(0)
+ end
+ end
+ end
+
+ describe "#address_line1" do
+ let(:attributes) { { bulk_upload:, field_19: "123 Sesame Street" } }
+
+ it "sets to given value" do
+ expect(parser.log.address_line1).to eql("123 Sesame Street")
+ end
+ end
+
+ describe "#address_line2" do
+ let(:attributes) { { bulk_upload:, field_20: "Cookie Town" } }
+
+ it "sets to given value" do
+ expect(parser.log.address_line2).to eql("Cookie Town")
+ end
+ end
+
+ describe "#town_or_city" do
+ let(:attributes) { { bulk_upload:, field_21: "London" } }
+
+ it "sets to given value" do
+ expect(parser.log.town_or_city).to eql("London")
+ end
+ end
+
+ describe "#county" do
+ let(:attributes) { { bulk_upload:, field_22: "Greater London" } }
+
+ it "sets to given value" do
+ expect(parser.log.county).to eql("Greater London")
+ end
+ end
+
[
%w[age1_known age1 field_46],
%w[age2_known age2 field_52],
diff --git a/spec/support/bulk_upload/log_to_csv.rb b/spec/support/bulk_upload/log_to_csv.rb
index 86167376d..a2d8c2f5f 100644
--- a/spec/support/bulk_upload/log_to_csv.rb
+++ b/spec/support/bulk_upload/log_to_csv.rb
@@ -29,11 +29,11 @@ class BulkUpload::LogToCsv
to_2022_row + [
log.needstype,
log.location&.id,
- nil, # uprn,
- nil, # address_line_1,
- nil, # address_line_2,
- nil, # town_or_city,
- nil, # county,
+ log.uprn,
+ log.address_line1,
+ log.address_line2,
+ log.town_or_city,
+ log.county,
]
end
From 2440e8a2efdf21673922c3afc2a0eeeadef4311b Mon Sep 17 00:00:00 2001
From: James Rose
Date: Thu, 23 Mar 2023 15:56:41 +0000
Subject: [PATCH 18/31] Update service charge validations (#1428)
* Update service charge validations
* Create location deactivation periods instead of setting a scheme end date
* Add test for deactivation period
* Update ranges in tests
* Remove scheme validation test
* Check that the location gets confirmed
---------
Co-authored-by: Kat
---
app/models/validations/date_validations.rb | 7 ----
.../validations/financial_validations.rb | 8 ++--
.../imports/scheme_location_import_service.rb | 24 ++++++-----
config/locales/en.yml | 8 ++--
.../validations/date_validations_spec.rb | 8 ----
.../validations/financial_validations_spec.rb | 42 +++++++++----------
.../scheme_location_import_service_spec.rb | 13 +++++-
7 files changed, 54 insertions(+), 56 deletions(-)
diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb
index ee7789171..744f636dc 100644
--- a/app/models/validations/date_validations.rb
+++ b/app/models/validations/date_validations.rb
@@ -37,13 +37,6 @@ module Validations::DateValidations
record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after")
end
- if record.scheme_id.present?
- scheme_end_date = record.scheme.end_date
- if scheme_end_date.present? && record.startdate > scheme_end_date
- record.errors.add :startdate, I18n.t("validations.setup.startdate.before_scheme_end_date")
- end
- end
-
if record["voiddate"].present? && record.startdate < record["voiddate"]
record.errors.add :startdate, I18n.t("validations.setup.startdate.after_void_date")
end
diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb
index 6179d05aa..71371ec71 100644
--- a/app/models/validations/financial_validations.rb
+++ b/app/models/validations/financial_validations.rb
@@ -132,12 +132,12 @@ private
CHARGE_MAXIMUMS = {
scharge: {
private_registered_provider: {
- general_needs: 55,
- supported_housing: 280,
+ general_needs: 155,
+ supported_housing: 480,
},
local_authority: {
- general_needs: 45,
- supported_housing: 165,
+ general_needs: 155,
+ supported_housing: 365,
},
},
pscharge: {
diff --git a/app/services/imports/scheme_location_import_service.rb b/app/services/imports/scheme_location_import_service.rb
index ab5faad27..a26139aec 100644
--- a/app/services/imports/scheme_location_import_service.rb
+++ b/app/services/imports/scheme_location_import_service.rb
@@ -35,7 +35,6 @@ module Imports
primary_client_group: attributes["primary_client_group"],
secondary_client_group: attributes["secondary_client_group"],
sensitive: attributes["sensitive"],
- end_date: attributes["end_date"],
# These values were set by the scheme import (management groups)
owning_organisation_id: source_scheme.owning_organisation_id,
service_name: source_scheme.service_name,
@@ -43,7 +42,7 @@ module Imports
old_id: source_scheme.old_id,
old_visible_id: source_scheme.old_visible_id,
)
- confirm_scheme(scheme)
+ confirm_scheme_or_location(scheme)
scheme.save! && scheme
rescue ActiveRecord::RecordInvalid
@logger.error("Scheme #{source_scheme.old_visible_id}: Failed to import")
@@ -59,18 +58,17 @@ module Imports
primary_client_group: attributes["primary_client_group"],
secondary_client_group: attributes["secondary_client_group"],
sensitive: attributes["sensitive"],
- end_date: attributes["end_date"],
}
- confirm_scheme(scheme)
+ confirm_scheme_or_location(scheme)
scheme.save! && scheme
end
- def confirm_scheme(scheme)
- scheme.confirmed = true
- scheme.validate_confirmed
- unless scheme.errors.empty?
- scheme.confirmed = false
- scheme.errors.clear
+ def confirm_scheme_or_location(obj)
+ obj.confirmed = true
+ obj.validate_confirmed
+ unless obj.errors.empty?
+ obj.confirmed = false
+ obj.errors.clear
end
end
@@ -99,7 +97,7 @@ module Imports
end
def add_location(scheme, attributes)
- Location.create!(
+ location = Location.create!(
name: attributes["location_name"],
postcode: attributes["postcode"],
mobility_type: attributes["mobility_type"],
@@ -110,6 +108,10 @@ module Imports
startdate: attributes["start_date"],
scheme:,
)
+ if attributes["end_date"]
+ location.location_deactivation_periods.create!(deactivation_date: attributes["end_date"])
+ end
+ location
rescue ActiveRecord::RecordNotUnique
@logger.warn("Location is already present with legacy ID #{attributes['location_old_id']}, skipping")
rescue ActiveRecord::RecordInvalid
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 56caa6a59..215a611b4 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -253,11 +253,11 @@ en:
less_than_shortfall: "Enter an amount that is more than the shortfall in basic rent"
scharge:
private_registered_provider:
- general_needs: "Enter a value for the service charge between £0 and £55 per week if the landlord is a private registered provider and it is a general needs letting"
- supported_housing: "Enter a value for the service charge between £0 and £280 per week if the landlord is a private registered provider and it is a supported housing letting"
+ general_needs: "Enter a value for the service charge between £0 and £155 per week if the landlord is a private registered provider and it is a general needs letting"
+ supported_housing: "Enter a value for the service charge between £0 and £480 per week if the landlord is a private registered provider and it is a supported housing letting"
local_authority:
- general_needs: "Enter a value for the service charge between £0 and £45 per week if the landlord is a local authority and it is a general needs letting"
- supported_housing: "Enter a value for the service charge between £0 and £165 per week if the landlord is a local authority and it is a supported housing letting"
+ general_needs: "Enter a value for the service charge between £0 and £155 per week if the landlord is a local authority and it is a general needs letting"
+ supported_housing: "Enter a value for the service charge between £0 and £365 per week if the landlord is a local authority and it is a supported housing letting"
pscharge:
private_registered_provider:
general_needs: "Enter a value for the personal service charge between £0 and £30 per week if the landlord is a private registered provider and it is a general needs letting"
diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb
index cd6e38f50..410da4f0c 100644
--- a/spec/models/validations/date_validations_spec.rb
+++ b/spec/models/validations/date_validations_spec.rb
@@ -21,14 +21,6 @@ RSpec.describe Validations::DateValidations do
expect(record.errors["startdate"]).to be_empty
end
- it "validates that the tenancy start date is before the end date of the chosen scheme if it has an end date" do
- record.startdate = Time.zone.today - 3.days
- record.scheme = scheme
- date_validator.validate_startdate(record)
- expect(record.errors["startdate"])
- .to include(match I18n.t("validations.setup.startdate.before_scheme_end_date"))
- end
-
it "validates that the tenancy start date is after the void date if it has a void date" do
record.startdate = Time.zone.local(2022, 1, 1)
record.voiddate = Time.zone.local(2022, 2, 1)
diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb
index c2fe3b963..1f40f7cbc 100644
--- a/spec/models/validations/financial_validations_spec.rb
+++ b/spec/models/validations/financial_validations_spec.rb
@@ -263,15 +263,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 56 },
+ charge: { field: "scharge", value: 156 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 300 },
+ charge: { field: "scharge", value: 672 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 111 },
+ charge: { field: "scharge", value: 311 },
},
{
period: { label: "weekly", value: 1 },
@@ -308,15 +308,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 54 },
+ charge: { field: "scharge", value: 154 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 220 },
+ charge: { field: "scharge", value: 670 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 109 },
+ charge: { field: "scharge", value: 309 },
},
{
period: { label: "weekly", value: 1 },
@@ -357,15 +357,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 281 },
+ charge: { field: "scharge", value: 481 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 1225 },
+ charge: { field: "scharge", value: 2081 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 561 },
+ charge: { field: "scharge", value: 961 },
},
{
period: { label: "weekly", value: 1 },
@@ -402,15 +402,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 280 },
+ charge: { field: "scharge", value: 366 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 1200 },
+ charge: { field: "scharge", value: 1582 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 559 },
+ charge: { field: "scharge", value: 731 },
},
{
period: { label: "weekly", value: 1 },
@@ -455,15 +455,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 46 },
+ charge: { field: "scharge", value: 156 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 200 },
+ charge: { field: "scharge", value: 672 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 91 },
+ charge: { field: "scharge", value: 311 },
},
{
period: { label: "weekly", value: 1 },
@@ -549,15 +549,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 165.90 },
+ charge: { field: "scharge", value: 365.90 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 750 },
+ charge: { field: "scharge", value: 2081 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 330.50 },
+ charge: { field: "scharge", value: 961 },
},
{
period: { label: "weekly", value: 1 },
@@ -617,15 +617,15 @@ RSpec.describe Validations::FinancialValidations do
[{
period: { label: "weekly", value: 1 },
- charge: { field: "scharge", value: 120.88 },
+ charge: { field: "scharge", value: 364.88 },
},
{
period: { label: "monthly", value: 4 },
- charge: { field: "scharge", value: 608 },
+ charge: { field: "scharge", value: 1200 },
},
{
period: { label: "every 2 weeks", value: 2 },
- charge: { field: "scharge", value: 329.99 },
+ charge: { field: "scharge", value: 700.99 },
},
{
period: { label: "weekly", value: 1 },
diff --git a/spec/services/imports/scheme_location_import_service_spec.rb b/spec/services/imports/scheme_location_import_service_spec.rb
index e74067cae..186fba818 100644
--- a/spec/services/imports/scheme_location_import_service_spec.rb
+++ b/spec/services/imports/scheme_location_import_service_spec.rb
@@ -16,6 +16,11 @@ RSpec.describe Imports::SchemeLocationImportService do
File.open("#{directory}/#{filename}.xml")
end
+ before do
+ WebMock.stub_request(:get, /api.postcodes.io\/postcodes/)
+ .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {})
+ end
+
context "when importing scheme locations" do
let(:remote_folder) { "schemes" }
@@ -145,6 +150,7 @@ RSpec.describe Imports::SchemeLocationImportService do
expect(location.old_visible_id).to eq("10")
expect(location.startdate).to eq("1900-01-01")
expect(location.scheme).to eq(scheme)
+ expect(location.confirmed).to eq(true)
end
it "matches expected schemes values" do
@@ -156,10 +162,15 @@ RSpec.describe Imports::SchemeLocationImportService do
expect(location.scheme.primary_client_group).to eq("Older people with support needs")
expect(location.scheme.secondary_client_group).to be_nil
expect(location.scheme.sensitive).to eq("No")
- expect(location.scheme.end_date).to eq("2050-12-31")
expect(location.scheme.confirmed).to be_truthy
end
+ it "creates a deactivation period" do
+ location = location_service.create_scheme_location(location_xml)
+ expect(location.location_deactivation_periods.count).to eq(1)
+ expect(location.location_deactivation_periods.first.deactivation_date).to eq(Time.zone.local(2050, 12, 31))
+ end
+
context "and we import the same location twice" do
before { location_service.create_scheme_location(location_xml) }
From fa8676b8eaec6031d9265f1613fce673c7835a81 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Thu, 23 Mar 2023 15:57:05 +0000
Subject: [PATCH 19/31] Lettings log import validations (#1463)
* Clear import fields failing non_temp_accommodation validation
* Clear joint tenancy if there is only 1 person in the household
* Clear offered if the value is above the maximum of 20
* Display error message on ecstat
* Remove ecstat if the income is too high for it
---
.../validations/financial_validations.rb | 1 +
.../validations/household_validations.rb | 2 +-
.../validations/property_validations.rb | 2 +-
app/models/validations/tenancy_validations.rb | 2 +-
.../imports/lettings_logs_import_service.rb | 21 ++++
config/locales/en.yml | 2 +
.../0ead17cb-1668-442d-898c-0d52879ff592.xml | 1 +
.../lettings_logs_import_service_spec.rb | 111 ++++++++++++++++++
8 files changed, 139 insertions(+), 3 deletions(-)
diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb
index 71371ec71..f39c17af7 100644
--- a/app/models/validations/financial_validations.rb
+++ b/app/models/validations/financial_validations.rb
@@ -25,6 +25,7 @@ module Validations::FinancialValidations
if record.ecstat1 && record.weekly_net_income
if record.weekly_net_income > record.applicable_income_range.hard_max
record.errors.add :earnings, :over_hard_max, message: I18n.t("validations.financial.earnings.over_hard_max", hard_max: record.applicable_income_range.hard_max)
+ record.errors.add :ecstat1, :over_hard_max, message: I18n.t("validations.financial.ecstat.over_hard_max", hard_max: record.applicable_income_range.hard_max)
end
if record.weekly_net_income < record.applicable_income_range.hard_min
diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb
index afa7867ff..0b871fce0 100644
--- a/app/models/validations/household_validations.rb
+++ b/app/models/validations/household_validations.rb
@@ -63,7 +63,7 @@ module Validations::HouseholdValidations
def validate_previous_housing_situation(record)
if record.is_relet_to_temp_tenant? && !record.previous_tenancy_was_temporary?
- record.errors.add :prevten, I18n.t("validations.household.prevten.non_temp_accommodation")
+ record.errors.add :prevten, :non_temp_accommodation, message: I18n.t("validations.household.prevten.non_temp_accommodation")
end
if record.age1.present? && record.age1 > 19 && record.previous_tenancy_was_foster_care?
diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb
index 2e53b8385..dafe6f6dd 100644
--- a/app/models/validations/property_validations.rb
+++ b/app/models/validations/property_validations.rb
@@ -16,7 +16,7 @@ module Validations::PropertyValidations
end
if record.offered.negative? || record.offered > 20
- record.errors.add :offered, I18n.t("validations.property.offered.relet_number")
+ record.errors.add :offered, :over_20, message: I18n.t("validations.property.offered.relet_number")
end
end
diff --git a/app/models/validations/tenancy_validations.rb b/app/models/validations/tenancy_validations.rb
index e2ea108cf..5e1ec4a3c 100644
--- a/app/models/validations/tenancy_validations.rb
+++ b/app/models/validations/tenancy_validations.rb
@@ -43,7 +43,7 @@ module Validations::TenancyValidations
return unless record.collection_start_year && record.joint
if record.hhmemb == 1 && record.joint != 2 && record.collection_start_year >= 2022
- record.errors.add :joint, I18n.t("validations.tenancy.not_joint")
+ record.errors.add :joint, :not_joint_tenancy, message: I18n.t("validations.tenancy.not_joint")
record.errors.add :hhmemb, I18n.t("validations.tenancy.joint_more_than_one_member")
end
end
diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb
index 9e5de20ba..ecd32c51d 100644
--- a/app/services/imports/lettings_logs_import_service.rb
+++ b/app/services/imports/lettings_logs_import_service.rb
@@ -311,6 +311,27 @@ module Imports
attributes.delete("prevten")
attributes.delete("age1")
save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:prevten, :non_temp_accommodation)
+ @logger.warn("Log #{lettings_log.old_id}: Removing vacancy reason and previous tenancy since this accommodation is not temporary")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("prevten")
+ attributes.delete("rsnvac")
+ save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:joint, :not_joint_tenancy)
+ @logger.warn("Log #{lettings_log.old_id}: Removing joint tenancy as there is only 1 person in the household")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("joint")
+ save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:offered, :over_20)
+ @logger.warn("Log #{lettings_log.old_id}: Removing offered as the value is above the maximum of 20")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("offered")
+ save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:earnings, :over_hard_max)
+ @logger.warn("Log #{lettings_log.old_id}: Removing working situation because income is too high for it")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("ecstat1")
+ save_lettings_log(attributes, previous_status)
else
@logger.error("Log #{lettings_log.old_id}: Failed to import")
lettings_log.errors.each do |error|
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 215a611b4..526dd8347 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -272,6 +272,8 @@ en:
local_authority:
general_needs: "Enter a value for the support charge between £0 and £60 per week if the landlord is a local authority and it is a general needs letting"
supported_housing: "Enter a value for the support charge between £0 and £120 per week if the landlord is a local authority and it is a supported housing letting"
+ ecstat:
+ over_hard_max: "Net income of £%{hard_max} per week is too high for given the tenant’s working situation"
brent:
below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms"
above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms"
diff --git a/spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml b/spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml
index c43bcf0bf..15f97ce5b 100644
--- a/spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml
+++ b/spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml
@@ -119,6 +119,7 @@
Yes
2 No
+ 2 No
diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb
index 5b56efdfb..89dd6e0c4 100644
--- a/spec/services/imports/lettings_logs_import_service_spec.rb
+++ b/spec/services/imports/lettings_logs_import_service_spec.rb
@@ -366,6 +366,81 @@ RSpec.describe Imports::LettingsLogsImportService do
end
end
+ context "and this is a non temporary acommodation" do
+ before do
+ lettings_log_xml.at_xpath("//xmlns:Q27").content = "9"
+ lettings_log_xml.at_xpath("//xmlns:Q11").content = "4"
+ lettings_log_xml.at_xpath("//xmlns:VDAY").content = ""
+ lettings_log_xml.at_xpath("//xmlns:VMONTH").content = ""
+ lettings_log_xml.at_xpath("//xmlns:VYEAR").content = ""
+ lettings_log_xml.at_xpath("//xmlns:MRCDAY").content = ""
+ lettings_log_xml.at_xpath("//xmlns:MRCMONTH").content = ""
+ lettings_log_xml.at_xpath("//xmlns:MRCYEAR").content = ""
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing vacancy reason and previous tenancy since this accommodation is not temporary/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the referral answer" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.rsnvac).to be_nil
+ expect(lettings_log.prevten).to be_nil
+ end
+ end
+
+ context "and the number the property was relet is over 20" do
+ before do
+ lettings_log_xml.at_xpath("//xmlns:Q20").content = "25"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing offered as the value is above the maximum of 20/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the referral answer" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.offered).to be_nil
+ end
+ end
+
+ context "and income over the max" do
+ before do
+ lettings_log_xml.at_xpath("//xmlns:Q8Money").content = "25000"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing working situation because income is too high for it/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the referral answer" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.ecstat1).to be_nil
+ expect(lettings_log.earnings).to eq(25_000)
+ end
+ end
+
context "and the net income soft validation is triggered (net_income_value_check)" do
before do
lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly"
@@ -560,5 +635,41 @@ RSpec.describe Imports::LettingsLogsImportService do
.to change(OrganisationRelationship, :count).by(1)
end
end
+
+ context "when this is a joint tenancy with 1 person in the household" do
+ let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }
+ let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id) }
+ let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) }
+
+ before do
+ lettings_log_xml.at_xpath("//xmlns:joint").content = "1"
+ lettings_log_xml.at_xpath("//xmlns:HHMEMB").content = "1"
+ lettings_log_xml.at_xpath("//xmlns:P2Age").content = ""
+ lettings_log_xml.at_xpath("//xmlns:P2Rel").content = ""
+ lettings_log_xml.at_xpath("//xmlns:P2Sex").content = ""
+ lettings_log_xml.at_xpath("//xmlns:P1Nat").content = "18"
+ lettings_log_xml.at_xpath("//xmlns:P2Eco").content = ""
+ lettings_log_xml.at_xpath("//xmlns:DAY").content = "2"
+ lettings_log_xml.at_xpath("//xmlns:MONTH").content = "10"
+ lettings_log_xml.at_xpath("//xmlns:YEAR").content = "2022"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing joint tenancy as there is only 1 person in the household/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the referral answer" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.joint).to be_nil
+ expect(lettings_log.hhmemb).to eq(1)
+ end
+ end
end
end
From 0966bd6869b3eabbea1951615548f9268ae3e253 Mon Sep 17 00:00:00 2001
From: natdeanlewissoftwire
<94526761+natdeanlewissoftwire@users.noreply.github.com>
Date: Fri, 24 Mar 2023 09:25:56 +0000
Subject: [PATCH 20/31] CLDC-2020 Add saledate less than 2 weeks from today
validation (#1446)
* feat: copy updates and add saledate validation
* feat: rename methods and enable feature toggle
* feat: rename methods and enable feature toggle
* test: add tests
* refactor: ruby police
* feat: fix tests
* refactor: readability
* feat: enable validation on review apps
* db:update
---
app/models/validations/date_validations.rb | 2 +-
.../validations/sales/setup_validations.rb | 10 +++-
config/initializers/feature_toggle.rb | 4 ++
config/locales/en.yml | 17 ++++---
db/schema.rb | 2 +-
spec/helpers/tasklist_helper_spec.rb | 4 +-
spec/models/sales_log_spec.rb | 2 +-
.../sale_information_validations_spec.rb | 8 +--
.../sales/setup_validations_spec.rb | 50 +++++++++++++++----
spec/requests/sales_logs_controller_spec.rb | 19 +++++--
10 files changed, 87 insertions(+), 31 deletions(-)
diff --git a/app/models/validations/date_validations.rb b/app/models/validations/date_validations.rb
index 744f636dc..ae5d7ee19 100644
--- a/app/models/validations/date_validations.rb
+++ b/app/models/validations/date_validations.rb
@@ -33,7 +33,7 @@ module Validations::DateValidations
def validate_startdate(record)
return unless record.startdate && date_valid?("startdate", record)
- if FeatureToggle.startdate_two_week_validation_enabled? && record.startdate > Time.zone.today + 14
+ if FeatureToggle.startdate_two_week_validation_enabled? && record.startdate > Time.zone.today + 14.days
record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after")
end
diff --git a/app/models/validations/sales/setup_validations.rb b/app/models/validations/sales/setup_validations.rb
index e76993907..1618ac3d9 100644
--- a/app/models/validations/sales/setup_validations.rb
+++ b/app/models/validations/sales/setup_validations.rb
@@ -2,7 +2,7 @@ module Validations::Sales::SetupValidations
include Validations::SharedValidations
include CollectionTimeHelper
- def validate_saledate(record)
+ def validate_saledate_collection_year(record)
return unless record.saledate && date_valid?("saledate", record) && FeatureToggle.saledate_collection_window_validation_enabled?
unless record.saledate.between?(active_collection_start_date, current_collection_end_date)
@@ -10,6 +10,14 @@ module Validations::Sales::SetupValidations
end
end
+ def validate_saledate_two_weeks(record)
+ return unless record.saledate && date_valid?("saledate", record) && FeatureToggle.saledate_two_week_validation_enabled?
+
+ if record.saledate > Time.zone.today + 14.days
+ record.errors.add :saledate, I18n.t("validations.setup.saledate.later_than_14_days_after")
+ end
+ end
+
private
def active_collection_start_date
diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb
index e00a7190b..6c889bcc5 100644
--- a/config/initializers/feature_toggle.rb
+++ b/config/initializers/feature_toggle.rb
@@ -12,6 +12,10 @@ class FeatureToggle
Rails.env.production? || Rails.env.test? || Rails.env.staging?
end
+ def self.saledate_two_week_validation_enabled?
+ Rails.env.production? || Rails.env.test? || Rails.env.staging? || Rails.env.review?
+ end
+
def self.sales_log_enabled?
true
end
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 526dd8347..a7a5e5400 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -155,6 +155,7 @@ en:
intermediate_rent_product_name:
blank: "Enter name of other intermediate rent product"
saledate:
+ later_than_14_days_after: "Sale completion date must not be later than 14 days from today’s date"
current_collection_year:
Enter a date within the %{current_start_year_short}/%{current_end_year_short} collection year, which is between %{current_start_year_long} and %{current_end_year_long}
previous_and_current_collection_year:
@@ -470,16 +471,16 @@ en:
social_homebuy: "Social HomeBuy buyers should not have lived here before"
rent_to_buy: "Rent to Buy buyers should not have lived here before"
hodate:
- must_be_before_saledate: "Practical completion or handover date must be before exchange date"
- must_be_less_than_3_years_from_saledate: "You told us practical completion or handover date is more than 3 years before completion date"
+ must_be_before_saledate: "Practical completion or handover date must be before sale completion date"
+ must_be_less_than_3_years_from_saledate: "You told us practical completion or handover date is more than 3 years before sale completion date"
exdate:
- must_be_before_saledate: "Contract exchange date must be before completion date"
- must_be_less_than_1_year_from_saledate: "Contract exchange date must be less than 1 year before completion date"
+ must_be_before_saledate: "Contract exchange date must be before sale completion date"
+ must_be_less_than_1_year_from_saledate: "Contract exchange date must be less than 1 year before sale completion date"
saledate:
- must_be_after_exdate: "Completion date must be after contract exchange date"
- must_be_less_than_1_year_from_exdate: "Completion date must be less than 1 year after contract exchange date"
- must_be_less_than_3_years_from_hodate: "You told us completion date is more than 3 years after practical completion or handover date"
- must_be_after_hodate: "Completion date must be after practical completion or handover date"
+ must_be_after_exdate: "Sale completion date must be after contract exchange date"
+ must_be_less_than_1_year_from_exdate: "Sale completion date must be less than 1 year after contract exchange date"
+ must_be_less_than_3_years_from_hodate: "You told us sale completion date is more than 3 years after practical completion or handover date"
+ must_be_after_hodate: "Sale completion date must be after practical completion or handover date"
previous_property_type:
property_type_bedsit: "A bedsit cannot have more than 1 bedroom"
discounted_ownership_value: "Mortgage, deposit, and grant total must equal £%{value_with_discount}"
diff --git a/db/schema.rb b/db/schema.rb
index 92b0d9a63..225129dfd 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -569,8 +569,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_20_084057) do
t.string "town_or_city"
t.string "county"
t.integer "nationalbuy2"
- t.integer "student_not_child_value_check"
t.integer "discounted_sale_value_check"
+ t.integer "student_not_child_value_check"
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true
diff --git a/spec/helpers/tasklist_helper_spec.rb b/spec/helpers/tasklist_helper_spec.rb
index b4e26437b..bd1bdb61f 100644
--- a/spec/helpers/tasklist_helper_spec.rb
+++ b/spec/helpers/tasklist_helper_spec.rb
@@ -81,7 +81,7 @@ RSpec.describe TasklistHelper do
context "with sales log" do
context "when collection_period_open? == true" do
let(:now) { Time.utc(2022, 6, 1) }
- let(:sales_log) { create(:sales_log, :completed) }
+ let(:sales_log) { create(:sales_log, :completed, saledate: now) }
it "returns relevant text" do
expect(review_log_text(sales_log)).to eq(
@@ -92,7 +92,7 @@ RSpec.describe TasklistHelper do
context "when collection_period_open? == false" do
let(:now) { Time.utc(2022, 6, 1) }
- let!(:sales_log) { create(:sales_log, :completed) }
+ let!(:sales_log) { create(:sales_log, :completed, saledate: now) }
it "returns relevant text" do
Timecop.freeze(now + 1.year) do
diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb
index 4bc90da37..511f1820b 100644
--- a/spec/models/sales_log_spec.rb
+++ b/spec/models/sales_log_spec.rb
@@ -302,7 +302,7 @@ RSpec.describe SalesLog, type: :model do
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {})
- Timecop.freeze(2023, 4, 1)
+ Timecop.freeze(2023, 5, 2)
Singleton.__init__(FormHandler)
end
diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb
index c34738de7..3a8944e79 100644
--- a/spec/models/validations/sales/sale_information_validations_spec.rb
+++ b/spec/models/validations/sales/sale_information_validations_spec.rb
@@ -115,10 +115,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
sale_information_validator.validate_exchange_date(record)
expect(record.errors[:exdate]).to eq(
- ["Contract exchange date must be less than 1 year before completion date"],
+ ["Contract exchange date must be less than 1 year before sale completion date"],
)
expect(record.errors[:saledate]).to eq(
- ["Completion date must be less than 1 year after contract exchange date"],
+ ["Sale completion date must be less than 1 year after contract exchange date"],
)
end
end
@@ -130,10 +130,10 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
sale_information_validator.validate_exchange_date(record)
expect(record.errors[:exdate]).to eq(
- ["Contract exchange date must be before completion date"],
+ ["Contract exchange date must be before sale completion date"],
)
expect(record.errors[:saledate]).to eq(
- ["Completion date must be after contract exchange date"],
+ ["Sale completion date must be after contract exchange date"],
)
end
end
diff --git a/spec/models/validations/sales/setup_validations_spec.rb b/spec/models/validations/sales/setup_validations_spec.rb
index 136e239d3..a85177aab 100644
--- a/spec/models/validations/sales/setup_validations_spec.rb
+++ b/spec/models/validations/sales/setup_validations_spec.rb
@@ -5,13 +5,13 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:validator_class) { Class.new { include Validations::Sales::SetupValidations } }
- describe "#validate_saledate" do
+ describe "#validate_saledate_collection_year" do
context "with sales_in_crossover_period == false" do
context "when saledate is blank" do
let(:record) { build(:sales_log, saledate: nil) }
it "does not add an error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors).to be_empty
end
@@ -21,7 +21,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2023, 1, 1)) }
it "does not add an error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors).to be_empty
end
@@ -31,7 +31,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 1, 1)) }
it "adds error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023")
end
@@ -41,7 +41,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) }
it "adds error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors[:saledate]).to include("Enter a date within the 22/23 collection year, which is between 1st April 2022 and 31st March 2023")
end
@@ -61,7 +61,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: nil) }
it "does not add an error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors).to be_empty
end
@@ -71,7 +71,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2024, 1, 1)) }
it "does not add an error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors).to be_empty
end
@@ -81,7 +81,7 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 5, 1)) }
it "adds error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025")
end
@@ -91,11 +91,43 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) }
it "adds error" do
- setup_validator.validate_saledate(record)
+ setup_validator.validate_saledate_collection_year(record)
expect(record.errors[:saledate]).to include("Enter a date within the 23/24 or 24/25 collection years, which is between 1st April 2023 and 31st March 2025")
end
end
end
end
+
+ describe "#validate_saledate_two_weeks" do
+ context "when saledate is blank" do
+ let(:record) { build(:sales_log, saledate: nil) }
+
+ it "does not add an error" do
+ setup_validator.validate_saledate_two_weeks(record)
+
+ expect(record.errors).to be_empty
+ end
+ end
+
+ context "when saledate is less than 14 days after today" do
+ let(:record) { build(:sales_log, saledate: Time.zone.today + 10.days) }
+
+ it "does not add an error" do
+ setup_validator.validate_saledate_two_weeks(record)
+
+ expect(record.errors).to be_empty
+ end
+ end
+
+ context "when saledate is more than 14 days after today" do
+ let(:record) { build(:sales_log, saledate: Time.zone.today + 15.days) }
+
+ it "adds an error" do
+ setup_validator.validate_saledate_two_weeks(record)
+
+ expect(record.errors[:saledate]).to include("Sale completion date must not be later than 14 days from today’s date")
+ end
+ end
+ end
end
diff --git a/spec/requests/sales_logs_controller_spec.rb b/spec/requests/sales_logs_controller_spec.rb
index 0a7ca0790..14341cd33 100644
--- a/spec/requests/sales_logs_controller_spec.rb
+++ b/spec/requests/sales_logs_controller_spec.rb
@@ -238,17 +238,28 @@ RSpec.describe SalesLogsController, type: :request do
Timecop.return
end
+ before do
+ Timecop.freeze(2022, 4, 1)
+ sales_log_2022.update!(saledate: Time.zone.local(2022, 4, 1))
+ Timecop.freeze(2023, 1, 1)
+ sales_log_2022.update!(saledate: Time.zone.local(2023, 1, 1))
+ end
+
+ after do
+ Timecop.unfreeze
+ end
+
let!(:sales_log_2022) do
FactoryBot.create(:sales_log, :completed,
owning_organisation: organisation,
- saledate: Time.zone.local(2022, 4, 1),
- created_by: user)
+ created_by: user,
+ saledate: Time.zone.today)
end
let!(:sales_log_2023) do
FactoryBot.create(:sales_log,
owning_organisation: organisation,
- saledate: Time.zone.local(2023, 1, 1),
- created_by: user)
+ created_by: user,
+ saledate: Time.zone.today)
end
it "shows sales logs for multiple selected statuses and years" do
From c9473c9362ee656f3dff210f99696359923b0f4a Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Fri, 24 Mar 2023 12:03:02 +0000
Subject: [PATCH 21/31] cannot create log if owning or mangaging data bad
(#1464)
- for bulk upload
---
.../lettings/year2022/row_parser.rb | 48 +++++++++++++------
.../lettings/year2023/row_parser.rb | 43 +++++++++++------
.../lettings/year2022/row_parser_spec.rb | 24 ++++++++++
.../lettings/year2023/row_parser_spec.rb | 32 +++++++++++++
4 files changed, 118 insertions(+), 29 deletions(-)
diff --git a/app/services/bulk_upload/lettings/year2022/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb
index b2bc24110..d9cc99505 100644
--- a/app/services/bulk_upload/lettings/year2022/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb
@@ -308,14 +308,14 @@ class BulkUpload::Lettings::Year2022::RowParser
validate :validate_dont_know_disabled_needs_conjunction
validate :validate_no_and_dont_know_disabled_needs_conjunction
- validate :validate_owning_org_permitted
- validate :validate_owning_org_owns_stock
- validate :validate_owning_org_exists
validate :validate_owning_org_data_given
+ validate :validate_owning_org_exists
+ validate :validate_owning_org_owns_stock
+ validate :validate_owning_org_permitted
- validate :validate_managing_org_related
- validate :validate_managing_org_exists
validate :validate_managing_org_data_given
+ validate :validate_managing_org_exists
+ validate :validate_managing_org_related
validate :validate_scheme_related
validate :validate_scheme_exists
@@ -436,19 +436,26 @@ private
def validate_managing_org_related
if owning_organisation && managing_organisation && !owning_organisation.can_be_managed_by?(organisation: managing_organisation)
block_log_creation!
- errors.add(:field_113, "This managing organisation does not have a relationship with the owning organisation")
+
+ if errors[:field_113].blank?
+ errors.add(:field_113, "This managing organisation does not have a relationship with the owning organisation")
+ end
end
end
def validate_managing_org_exists
if managing_organisation.nil?
- errors.delete(:field_113)
- errors.add(:field_113, "The managing organisation code is incorrect")
+ block_log_creation!
+
+ if errors[:field_113].blank?
+ errors.add(:field_113, "The managing organisation code is incorrect")
+ end
end
end
def validate_managing_org_data_given
if field_113.blank?
+ block_log_creation!
errors.add(:field_113, "The managing organisation code is incorrect", category: :setup)
end
end
@@ -456,29 +463,40 @@ private
def validate_owning_org_owns_stock
if owning_organisation && !owning_organisation.holds_own_stock?
block_log_creation!
- errors.delete(:field_111)
- errors.add(:field_111, "The owning organisation code provided is for an organisation that does not own stock")
+
+ if errors[:field_111].blank?
+ errors.add(:field_111, "The owning organisation code provided is for an organisation that does not own stock")
+ end
end
end
def validate_owning_org_exists
if owning_organisation.nil?
- errors.delete(:field_111)
- errors.add(:field_111, "The owning organisation code is incorrect")
+ block_log_creation!
+
+ if errors[:field_111].blank?
+ errors.add(:field_111, "The owning organisation code is incorrect")
+ end
end
end
def validate_owning_org_data_given
if field_111.blank?
- errors.add(:field_111, "The owning organisation code is incorrect", category: :setup)
+ block_log_creation!
+
+ if errors[:field_111].blank?
+ errors.add(:field_111, "The owning organisation code is incorrect", category: :setup)
+ end
end
end
def validate_owning_org_permitted
if owning_organisation && !bulk_upload.user.organisation.affiliated_stock_owners.include?(owning_organisation)
block_log_creation!
- errors.delete(:field_111)
- errors.add(:field_111, "You do not have permission to add logs for this owning organisation")
+
+ if errors[:field_111].blank?
+ errors.add(:field_111, "You do not have permission to add logs for this owning organisation")
+ end
end
end
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index e4ba7cb82..dc2a04a66 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -311,14 +311,14 @@ class BulkUpload::Lettings::Year2023::RowParser
validate :validate_dont_know_disabled_needs_conjunction
validate :validate_no_and_dont_know_disabled_needs_conjunction
- validate :validate_owning_org_permitted
- validate :validate_owning_org_owns_stock
- validate :validate_owning_org_exists
validate :validate_owning_org_data_given
+ validate :validate_owning_org_exists
+ validate :validate_owning_org_owns_stock
+ validate :validate_owning_org_permitted
- validate :validate_managing_org_related
- validate :validate_managing_org_exists
validate :validate_managing_org_data_given
+ validate :validate_managing_org_exists
+ validate :validate_managing_org_related
validate :validate_scheme_related
validate :validate_scheme_exists
@@ -551,19 +551,26 @@ private
def validate_managing_org_related
if owning_organisation && managing_organisation && !owning_organisation.can_be_managed_by?(organisation: managing_organisation)
block_log_creation!
- errors.add(:field_2, "This managing organisation does not have a relationship with the owning organisation")
+
+ if errors[:field_2].blank?
+ errors.add(:field_2, "This managing organisation does not have a relationship with the owning organisation")
+ end
end
end
def validate_managing_org_exists
if managing_organisation.nil?
- errors.delete(:field_2)
- errors.add(:field_2, "The managing organisation code is incorrect")
+ block_log_creation!
+
+ if errors[:field_2].blank?
+ errors.add(:field_2, "The managing organisation code is incorrect")
+ end
end
end
def validate_managing_org_data_given
if field_2.blank?
+ block_log_creation!
errors.add(:field_2, "The managing organisation code is incorrect", category: :setup)
end
end
@@ -571,20 +578,26 @@ private
def validate_owning_org_owns_stock
if owning_organisation && !owning_organisation.holds_own_stock?
block_log_creation!
- errors.delete(:field_1)
- errors.add(:field_1, "The owning organisation code provided is for an organisation that does not own stock")
+
+ if errors[:field_1].blank?
+ errors.add(:field_1, "The owning organisation code provided is for an organisation that does not own stock")
+ end
end
end
def validate_owning_org_exists
if owning_organisation.nil?
- errors.delete(:field_1)
- errors.add(:field_1, "The owning organisation code is incorrect")
+ block_log_creation!
+
+ if errors[:field_1].blank?
+ errors.add(:field_1, "The owning organisation code is incorrect")
+ end
end
end
def validate_owning_org_data_given
if field_1.blank?
+ block_log_creation!
errors.add(:field_1, "The owning organisation code is incorrect", category: :setup)
end
end
@@ -592,8 +605,10 @@ private
def validate_owning_org_permitted
if owning_organisation && !bulk_upload.user.organisation.affiliated_stock_owners.include?(owning_organisation)
block_log_creation!
- errors.delete(:field_1)
- errors.add(:field_1, "You do not have permission to add logs for this owning organisation")
+
+ if errors[:field_1].blank?
+ errors.add(:field_1, "You do not have permission to add logs for this owning organisation")
+ end
end
end
diff --git a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
index f7848f690..6355bb3bd 100644
--- a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
@@ -634,6 +634,10 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
expect(setup_errors.find { |e| e.attribute == :field_111 }.message).to eql("The owning organisation code is incorrect")
end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
end
context "when cannot find owning org" do
@@ -642,6 +646,10 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
it "is not permitted" do
expect(parser.errors[:field_111]).to eql(["The owning organisation code is incorrect"])
end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
end
context "when org is not stock owning" do
@@ -674,12 +682,28 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
end
describe "#field_113" do # managing org
+ context "when blank" do
+ let(:attributes) { { bulk_upload:, field_113: "" } }
+
+ it "is not permitted" do
+ expect(parser.errors[:field_113]).to eql(["The managing organisation code is incorrect"])
+ end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
+ end
+
context "when cannot find managing org" do
let(:attributes) { { bulk_upload:, field_113: "donotexist" } }
it "is not permitted" do
expect(parser.errors[:field_113]).to eql(["The managing organisation code is incorrect"])
end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
end
context "when not affiliated with managing org" do
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 997624757..4d745f21e 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -585,12 +585,28 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
describe "#field_1" do # owning org
+ context "when blank" do
+ let(:attributes) { { bulk_upload:, field_1: "" } }
+
+ it "is not permitted" do
+ expect(parser.errors[:field_1]).to eql(["The owning organisation code is incorrect"])
+ end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
+ end
+
context "when cannot find owning org" do
let(:attributes) { { bulk_upload:, field_1: "donotexist" } }
it "is not permitted" do
expect(parser.errors[:field_1]).to eql(["The owning organisation code is incorrect"])
end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
end
context "when org is not stock owning" do
@@ -623,12 +639,28 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
describe "#field_2" do # managing org
+ context "when blank" do
+ let(:attributes) { { bulk_upload:, field_2: "" } }
+
+ it "is not permitted" do
+ expect(parser.errors[:field_2]).to eql(["The managing organisation code is incorrect"])
+ end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
+ end
+
context "when cannot find managing org" do
let(:attributes) { { bulk_upload:, field_2: "donotexist" } }
it "is not permitted" do
expect(parser.errors[:field_2]).to eql(["The managing organisation code is incorrect"])
end
+
+ it "blocks log creation" do
+ expect(parser).to be_block_log_creation
+ end
end
context "when not affiliated with managing org" do
From cf46ae46fe64490f63129b65b8e57f584de764f1 Mon Sep 17 00:00:00 2001
From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Date: Fri, 24 Mar 2023 14:18:34 +0000
Subject: [PATCH 22/31] CLDC-2131 Update pregnancy validation (#1458)
* Remove hard pregnancy validation and update soft validation
* Remove validate_pregnancy references
* Don't care about the age in gender validation
---
.../validations/household_validations.rb | 6 --
app/models/validations/soft_validations.rb | 10 ++-
config/locales/en.yml | 4 +-
spec/features/form/page_routing_spec.rb | 1 -
.../validations/household_validations_spec.rb | 67 -------------------
.../validations/soft_validations_spec.rb | 11 ++-
spec/requests/form_controller_spec.rb | 4 --
7 files changed, 18 insertions(+), 85 deletions(-)
diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb
index 0b871fce0..e56a16783 100644
--- a/app/models/validations/household_validations.rb
+++ b/app/models/validations/household_validations.rb
@@ -35,12 +35,6 @@ module Validations::HouseholdValidations
end
end
- def validate_pregnancy(record)
- if (record.has_pregnancy? || record.pregnancy_refused?) && women_in_household(record) && !women_of_child_bearing_age_in_household(record)
- record.errors.add :preg_occ, I18n.t("validations.household.preg_occ.no_female")
- end
- end
-
def validate_household_number_of_other_members(record)
(2..8).each do |n|
validate_person_age_matches_economic_status(record, n)
diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb
index fc2c469ca..fbc5ab3b9 100644
--- a/app/models/validations/soft_validations.rb
+++ b/app/models/validations/soft_validations.rb
@@ -53,11 +53,11 @@ module Validations::SoftValidations
end
def no_females_in_a_pregnant_household?
- !females_in_the_household? && all_tenants_age_and_gender_information_completed? && preg_occ == 1
+ !females_in_the_household? && all_tenants_gender_information_completed? && preg_occ == 1
end
def female_in_pregnant_household_in_soft_validation_range?
- all_tenants_age_and_gender_information_completed? && (females_in_age_range(11, 15) || females_in_age_range(51, 65)) && !females_in_age_range(16, 50) && preg_occ == 1
+ all_tenants_age_and_gender_information_completed? && females_in_the_household? && !females_in_age_range(16, 50) && preg_occ == 1
end
def all_tenants_age_and_gender_information_completed?
@@ -66,6 +66,12 @@ module Validations::SoftValidations
end
end
+ def all_tenants_gender_information_completed?
+ (1..hhmemb).all? do |n|
+ public_send("sex#{n}").present? && details_known_or_lead_tenant?(n)
+ end
+ end
+
TWO_YEARS_IN_DAYS = 730
TEN_YEARS_IN_DAYS = 3650
diff --git a/config/locales/en.yml b/config/locales/en.yml
index a7a5e5400..7e514b17f 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -335,8 +335,6 @@ en:
leftreg:
question_required: "Tell us whether the person is still serving in the UK armed forces as you told us they’re a current or former regular"
question_not_required: "You cannot answer whether the person is still serving in the UK armed forces as you told us they’re not a current or former regular"
- preg_occ:
- no_female: "Enter ‘no’ as there are no female tenants aged 11-65 in the household"
age:
retired_male: "A male tenant who is retired must be 65 or over"
retired_female: "A female tenant who is retired must be 60 or over"
@@ -516,7 +514,7 @@ en:
pregnancy:
title: "You told us somebody in the household is pregnant"
no_females: "You also told us there are no female tenants living at the property."
- females_not_in_soft_age_range: "You also told us that any female tenants living at the property are in the following age ranges:"
+ females_not_in_soft_age_range: "You also told us that any female tenants living at the property are in the following age ranges:- under 16 years old
- over 50 years old
"
major_repairs_date:
title_text: "You told us the time between the start of the tenancy and the major repairs completion date is more than 2 years"
void_date:
diff --git a/spec/features/form/page_routing_spec.rb b/spec/features/form/page_routing_spec.rb
index 312e0752b..0ba8ece6e 100644
--- a/spec/features/form/page_routing_spec.rb
+++ b/spec/features/form/page_routing_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe "Form Page Routing" do
before do
allow(lettings_log.form).to receive(:end_date).and_return(Time.zone.today + 1.day)
- allow(validator).to receive(:validate_pregnancy).and_return(true)
sign_in user
end
diff --git a/spec/models/validations/household_validations_spec.rb b/spec/models/validations/household_validations_spec.rb
index daa3feef1..e1837a43d 100644
--- a/spec/models/validations/household_validations_spec.rb
+++ b/spec/models/validations/household_validations_spec.rb
@@ -60,73 +60,6 @@ RSpec.describe Validations::HouseholdValidations do
end
end
- describe "pregnancy validations" do
- context "when there are no female tenants" do
- it "validates that pregnancy can be yes" do
- record.preg_occ = 1
- record.sex1 = "M"
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"]).to be_empty
- end
-
- it "validates that pregnancy can be prefer not to say" do
- record.preg_occ = 3
- record.sex1 = "M"
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"]).to be_empty
- end
- end
-
- context "when there are female tenants" do
- context "but they are older than 65" do
- before { record.assign_attributes(sex1: "F", age1: 66, preg_occ: 1) }
-
- it "validates that pregnancy cannot be yes" do
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"])
- .to include(match I18n.t("validations.household.preg_occ.no_female"))
- end
- end
-
- context "and they are the lead tenant and under 65" do
- before { record.assign_attributes(sex1: "F", age1: 64, preg_occ: 1) }
-
- it "allows pregnancy to be set to yes" do
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"]).to be_empty
- end
- end
-
- context "and they are another household member and under 51" do
- before { record.assign_attributes(sex1: "M", age1: 25, sex3: "F", age3: 64, preg_occ: 1) }
-
- it "allows pregnancy to be set to yes" do
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"]).to be_empty
- end
- end
-
- context "and they are another household member and under 11" do
- before { record.assign_attributes(sex1: "M", age1: 25, sex3: "F", age3: 10, preg_occ: 1) }
-
- it "validates that pregnancy cannot be yes" do
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"])
- .to include(match I18n.t("validations.household.preg_occ.no_female"))
- end
- end
-
- context "and one tenant's age is unknown" do
- before { record.assign_attributes(sex1: "F", age1: nil, age1_known: 1, preg_occ: 1) }
-
- it "allows pregnancy to be set to yes" do
- household_validator.validate_pregnancy(record)
- expect(record.errors["preg_occ"]).to be_empty
- end
- end
- end
- end
-
describe "reason for leaving last settled home validations" do
let(:field) { "validations.other_field_not_required" }
let(:main_field_label) { "reason" }
diff --git a/spec/models/validations/soft_validations_spec.rb b/spec/models/validations/soft_validations_spec.rb
index b71d91a62..d355f2fbd 100644
--- a/spec/models/validations/soft_validations_spec.rb
+++ b/spec/models/validations/soft_validations_spec.rb
@@ -175,14 +175,21 @@ RSpec.describe Validations::SoftValidations do
end
end
- context "when female tenants are in 11-16 age range" do
+ context "when there are no female tenants and age of other tenants is unknown" do
+ it "shows the interruption screen" do
+ record.update!(sex1: "M", preg_occ: 1, hhmemb: 1, age1_known: 1)
+ expect(record.no_females_in_a_pregnant_household?).to be true
+ end
+ end
+
+ context "when female tenants are under 16" do
it "shows the interruption screen" do
record.update!(age2: 14, sex2: "F", preg_occ: 1, hhmemb: 2, details_known_2: 0, age2_known: 0, age1: 18, sex1: "M", age1_known: 0)
expect(record.female_in_pregnant_household_in_soft_validation_range?).to be true
end
end
- context "when female tenants are in 50-65 age range" do
+ context "when female tenants are over 50" do
it "shows the interruption screen" do
record.update!(age1: 54, sex1: "F", preg_occ: 1, hhmemb: 1, age1_known: 0)
expect(record.female_in_pregnant_household_in_soft_validation_range?).to be true
diff --git a/spec/requests/form_controller_spec.rb b/spec/requests/form_controller_spec.rb
index 9dce39af2..9787ce097 100644
--- a/spec/requests/form_controller_spec.rb
+++ b/spec/requests/form_controller_spec.rb
@@ -632,10 +632,6 @@ RSpec.describe FormController, type: :request do
}
end
- before do
- allow(validator).to receive(:validate_pregnancy).and_return(true)
- end
-
it "routes to the appropriate conditional page based on the question answer of the current page" do
post "/lettings-logs/#{lettings_log.id}/form", params: lettings_log_form_conditional_question_yes_params
expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/conditional-question-yes-page")
From 8d9c577e6979e93f9711b0f4fd384c79d1d5b2ff Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Fri, 24 Mar 2023 14:32:57 +0000
Subject: [PATCH 23/31] disable start date validation for staging (#1466)
---
config/initializers/feature_toggle.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb
index 6c889bcc5..de1c11fbd 100644
--- a/config/initializers/feature_toggle.rb
+++ b/config/initializers/feature_toggle.rb
@@ -5,7 +5,7 @@ class FeatureToggle
end
def self.startdate_collection_window_validation_enabled?
- Rails.env.production? || Rails.env.test? || Rails.env.staging?
+ Rails.env.production? || Rails.env.test?
end
def self.startdate_two_week_validation_enabled?
From ea810beab1c3b8ce73567fd74f5bb6f70ab7e21b Mon Sep 17 00:00:00 2001
From: Jack <113976590+bibblobcode@users.noreply.github.com>
Date: Fri, 24 Mar 2023 14:56:57 +0000
Subject: [PATCH 24/31] Address UPRN PO review (#1467)
* Fix question number rendering
* Update title copy
---
app/models/form/lettings/pages/address.rb | 2 +-
app/models/form/lettings/questions/address_line1.rb | 2 +-
app/models/form/lettings/questions/uprn_known.rb | 2 +-
app/models/form/sales/pages/address.rb | 2 +-
app/models/form/sales/questions/address_line1.rb | 2 +-
app/models/form/sales/questions/uprn_known.rb | 2 +-
spec/models/form/lettings/pages/address_spec.rb | 2 +-
spec/models/form/lettings/questions/address_line1_spec.rb | 4 ++--
spec/models/form/lettings/questions/uprn_known_spec.rb | 2 +-
spec/models/form/sales/pages/address_spec.rb | 2 +-
spec/models/form/sales/questions/address_line1_spec.rb | 4 ++--
spec/models/form/sales/questions/uprn_known_spec.rb | 2 +-
12 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/app/models/form/lettings/pages/address.rb b/app/models/form/lettings/pages/address.rb
index 6f88bad0d..cf6f73036 100644
--- a/app/models/form/lettings/pages/address.rb
+++ b/app/models/form/lettings/pages/address.rb
@@ -2,7 +2,7 @@ class Form::Lettings::Pages::Address < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "address"
- @header = "What is the property's address?"
+ @header = "Q12 - What is the property's address?"
end
def questions
diff --git a/app/models/form/lettings/questions/address_line1.rb b/app/models/form/lettings/questions/address_line1.rb
index 6f82edf45..b3288c82c 100644
--- a/app/models/form/lettings/questions/address_line1.rb
+++ b/app/models/form/lettings/questions/address_line1.rb
@@ -6,7 +6,7 @@ class Form::Lettings::Questions::AddressLine1 < ::Form::Question
@header = "Address line 1"
@type = "text"
@plain_label = true
- @question_number = 12
+ @check_answer_label = "Q12 - Address"
end
def hidden_in_check_answers?(log, _current_user = nil)
diff --git a/app/models/form/lettings/questions/uprn_known.rb b/app/models/form/lettings/questions/uprn_known.rb
index 6e3ce0302..d206885fb 100644
--- a/app/models/form/lettings/questions/uprn_known.rb
+++ b/app/models/form/lettings/questions/uprn_known.rb
@@ -3,7 +3,7 @@ class Form::Lettings::Questions::UprnKnown < ::Form::Question
super
@id = "uprn_known"
@check_answer_label = "UPRN known?"
- @header = "Do you know the property UPRN?"
+ @header = "Do you know the property's UPRN?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.
diff --git a/app/models/form/sales/pages/address.rb b/app/models/form/sales/pages/address.rb
index aa8ab7e0d..ca686d1b1 100644
--- a/app/models/form/sales/pages/address.rb
+++ b/app/models/form/sales/pages/address.rb
@@ -2,7 +2,7 @@ class Form::Sales::Pages::Address < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "address"
- @header = "What is the property's address?"
+ @header = "Q15 - What is the property's address?"
end
def questions
diff --git a/app/models/form/sales/questions/address_line1.rb b/app/models/form/sales/questions/address_line1.rb
index 2dd3a734e..a71229970 100644
--- a/app/models/form/sales/questions/address_line1.rb
+++ b/app/models/form/sales/questions/address_line1.rb
@@ -6,7 +6,7 @@ class Form::Sales::Questions::AddressLine1 < ::Form::Question
@header = "Address line 1"
@type = "text"
@plain_label = true
- @question_number = 15
+ @check_answer_label = "Q15 - Address"
end
def hidden_in_check_answers?(log, _current_user = nil)
diff --git a/app/models/form/sales/questions/uprn_known.rb b/app/models/form/sales/questions/uprn_known.rb
index 9f192f7de..b07b0b7d7 100644
--- a/app/models/form/sales/questions/uprn_known.rb
+++ b/app/models/form/sales/questions/uprn_known.rb
@@ -3,7 +3,7 @@ class Form::Sales::Questions::UprnKnown < ::Form::Question
super
@id = "uprn_known"
@check_answer_label = "UPRN known?"
- @header = "Do you know the property UPRN?"
+ @header = "Do you know the property's UPRN?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.
diff --git a/spec/models/form/lettings/pages/address_spec.rb b/spec/models/form/lettings/pages/address_spec.rb
index e4cf044b8..230d6964f 100644
--- a/spec/models/form/lettings/pages/address_spec.rb
+++ b/spec/models/form/lettings/pages/address_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Form::Lettings::Pages::Address, type: :model do
end
it "has the correct header" do
- expect(page.header).to eq("What is the property's address?")
+ expect(page.header).to eq("Q12 - What is the property's address?")
end
it "has the correct description" do
diff --git a/spec/models/form/lettings/questions/address_line1_spec.rb b/spec/models/form/lettings/questions/address_line1_spec.rb
index 781b0a748..e2600f0cc 100644
--- a/spec/models/form/lettings/questions/address_line1_spec.rb
+++ b/spec/models/form/lettings/questions/address_line1_spec.rb
@@ -20,11 +20,11 @@ RSpec.describe Form::Lettings::Questions::AddressLine1, type: :model do
end
it "has the correct question_number" do
- expect(question.question_number).to eq(12)
+ expect(question.question_number).to be_nil
end
it "has the correct check_answer_label" do
- expect(question.check_answer_label).to eq("Address")
+ expect(question.check_answer_label).to eq("Q12 - Address")
end
it "has the correct type" do
diff --git a/spec/models/form/lettings/questions/uprn_known_spec.rb b/spec/models/form/lettings/questions/uprn_known_spec.rb
index 1a0f810da..07eb72f8d 100644
--- a/spec/models/form/lettings/questions/uprn_known_spec.rb
+++ b/spec/models/form/lettings/questions/uprn_known_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Form::Lettings::Questions::UprnKnown, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("Do you know the property UPRN?")
+ expect(question.header).to eq("Do you know the property's UPRN?")
end
it "has the correct check_answer_label" do
diff --git a/spec/models/form/sales/pages/address_spec.rb b/spec/models/form/sales/pages/address_spec.rb
index d6979b6b4..43a054a1e 100644
--- a/spec/models/form/sales/pages/address_spec.rb
+++ b/spec/models/form/sales/pages/address_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Form::Sales::Pages::Address, type: :model do
end
it "has the correct header" do
- expect(page.header).to eq("What is the property's address?")
+ expect(page.header).to eq("Q15 - What is the property's address?")
end
it "has the correct description" do
diff --git a/spec/models/form/sales/questions/address_line1_spec.rb b/spec/models/form/sales/questions/address_line1_spec.rb
index 27c0179e2..f037f41cd 100644
--- a/spec/models/form/sales/questions/address_line1_spec.rb
+++ b/spec/models/form/sales/questions/address_line1_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Form::Sales::Questions::AddressLine1, type: :model do
end
it "has the correct question_number" do
- expect(question.question_number).to eq(15)
+ expect(question.question_number).to be_nil
end
it "has the correct id" do
@@ -24,7 +24,7 @@ RSpec.describe Form::Sales::Questions::AddressLine1, type: :model do
end
it "has the correct check_answer_label" do
- expect(question.check_answer_label).to eq("Address")
+ expect(question.check_answer_label).to eq("Q15 - Address")
end
it "has the correct type" do
diff --git a/spec/models/form/sales/questions/uprn_known_spec.rb b/spec/models/form/sales/questions/uprn_known_spec.rb
index 528e60a1f..457471568 100644
--- a/spec/models/form/sales/questions/uprn_known_spec.rb
+++ b/spec/models/form/sales/questions/uprn_known_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Form::Sales::Questions::UprnKnown, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("Do you know the property UPRN?")
+ expect(question.header).to eq("Do you know the property's UPRN?")
end
it "has the correct check_answer_label" do
From 9f3b2bba28955e8f1bcd0f31f53ee17f3878f793 Mon Sep 17 00:00:00 2001
From: Arthur Campbell <51094020+arfacamble@users.noreply.github.com>
Date: Fri, 24 Mar 2023 15:44:09 +0000
Subject: [PATCH 25/31] CLDC-2032 test log creation in crossover period (#1420)
* ensure that no form is added to the forms hash under the key "nil"
* add a test to ensure that the form handler does not add outdated forms to the forms hash with key nil
* remove unnecessary singleton reinitialisation
* remove a duplicated Timecop around block
---
app/models/form_handler.rb | 2 +-
spec/models/form_handler_spec.rb | 11 +++++++++--
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/app/models/form_handler.rb b/app/models/form_handler.rb
index 12ae4473b..b2d9168b2 100644
--- a/app/models/form_handler.rb
+++ b/app/models/form_handler.rb
@@ -47,7 +47,7 @@ class FormHandler
form = Form.new(form_path)
form_to_set = form_name_from_start_year(form.start_date.year, "lettings")
- forms[form_to_set] = form if forms[form_to_set].blank?
+ forms[form_to_set] = form if form_to_set && forms[form_to_set].blank?
end
end
diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb
index 417da6639..ec2ddbecc 100644
--- a/spec/models/form_handler_spec.rb
+++ b/spec/models/form_handler_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe FormHandler do
Singleton.__init__(described_class)
example.run
end
- Timecop.return
- Singleton.__init__(described_class)
end
context "when accessing a form in a different year" do
@@ -35,6 +33,15 @@ RSpec.describe FormHandler do
expect(all_forms.count).to be >= 1
expect(all_forms["current_sales"]).to be_a(Form)
end
+
+ context "when in 23/24 period or later" do
+ let(:now) { Time.utc(2023, 6, 7) }
+
+ it "does not load outdated forms" do
+ all_forms = form_handler.forms
+ expect(all_forms.keys).not_to include nil
+ end
+ end
end
describe "Get specific form" do
From d42a37c08e6d7c09abe852ee4fb45bca23c1eac7 Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Fri, 24 Mar 2023 18:25:15 +0000
Subject: [PATCH 26/31] permit at least one housing need (#1470)
---
.../bulk_upload/lettings/year2022/row_parser.rb | 2 +-
.../bulk_upload/lettings/year2023/row_parser.rb | 2 +-
.../bulk_upload/lettings/year2022/row_parser_spec.rb | 10 ++++++++++
.../bulk_upload/lettings/year2023/row_parser_spec.rb | 10 ++++++++++
4 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/app/services/bulk_upload/lettings/year2022/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb
index d9cc99505..34b65700e 100644
--- a/app/services/bulk_upload/lettings/year2022/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb
@@ -520,7 +520,7 @@ private
end
def validate_only_one_housing_needs_type
- if [field_55, field_56, field_57].compact.count.positive?
+ if [field_55, field_56, field_57].compact.count > 1
errors.add(:field_55, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
errors.add(:field_56, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
errors.add(:field_57, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index dc2a04a66..3c214a204 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -419,7 +419,7 @@ private
end
def validate_only_one_housing_needs_type
- if [field_83, field_84, field_85].compact.count.positive?
+ if [field_83, field_84, field_85].compact.count > 1
errors.add(:field_83, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
errors.add(:field_84, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
errors.add(:field_85, I18n.t("validations.household.housingneeds_type.only_one_option_permitted"))
diff --git a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
index 6355bb3bd..29c48006e 100644
--- a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
@@ -475,6 +475,16 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
end
describe "#field_55, #field_56, #field_57" do
+ context "when one item selected" do
+ let(:attributes) { { bulk_upload:, field_55: "1" } }
+
+ it "is permitted" do
+ expect(parser.errors[:field_55]).to be_blank
+ expect(parser.errors[:field_56]).to be_blank
+ expect(parser.errors[:field_57]).to be_blank
+ end
+ end
+
context "when more than one item selected" do
let(:attributes) { { bulk_upload:, field_55: "1", field_56: "1" } }
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 4d745f21e..1bb4dc99a 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -438,6 +438,16 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
describe "#field_83, #field_84, #field_85" do
+ context "when one item selected" do
+ let(:attributes) { { bulk_upload:, field_83: "1" } }
+
+ it "is permitted" do
+ expect(parser.errors[:field_83]).to be_blank
+ expect(parser.errors[:field_84]).to be_blank
+ expect(parser.errors[:field_85]).to be_blank
+ end
+ end
+
context "when more than one item selected" do
let(:attributes) { { bulk_upload:, field_83: "1", field_84: "1" } }
From b262178923c80b945f1f26c7c63c13348aaf9bb6 Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Fri, 24 Mar 2023 18:25:52 +0000
Subject: [PATCH 27/31] bulk upload ageN check depends on other fields (#1468)
- if other fields for a person are present but the age is not we ask
them to enter their age
---
.../lettings/year2022/row_parser.rb | 71 +++++++++++++------
.../lettings/year2023/row_parser.rb | 71 +++++++++++++------
.../lettings/year2022/row_parser_spec.rb | 10 +++
.../lettings/year2023/row_parser_spec.rb | 10 +++
4 files changed, 116 insertions(+), 46 deletions(-)
diff --git a/app/services/bulk_upload/lettings/year2022/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb
index 34b65700e..432897d0b 100644
--- a/app/services/bulk_upload/lettings/year2022/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb
@@ -866,28 +866,28 @@ private
attributes["tenancylength"] = field_11
attributes["declaration"] = field_132
- attributes["age1_known"] = (field_12 == "R" || field_12.blank? ? 1 : 0)
+ attributes["age1_known"] = age1_known?
attributes["age1"] = field_12 if attributes["age1_known"].zero? && field_12&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age2_known"] = (field_13 == "R" || field_13.blank? ? 1 : 0)
+ attributes["age2_known"] = age2_known?
attributes["age2"] = field_13 if attributes["age2_known"].zero? && field_13&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age3_known"] = (field_14 == "R" || field_14.blank? ? 1 : 0)
+ attributes["age3_known"] = age3_known?
attributes["age3"] = field_14 if attributes["age3_known"].zero? && field_14&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age4_known"] = (field_15 == "R" || field_15.blank? ? 1 : 0)
+ attributes["age4_known"] = age4_known?
attributes["age4"] = field_15 if attributes["age4_known"].zero? && field_15&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age5_known"] = (field_16 == "R" || field_16.blank? ? 1 : 0)
+ attributes["age5_known"] = age5_known?
attributes["age5"] = field_16 if attributes["age5_known"].zero? && field_16&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age6_known"] = (field_17 == "R" || field_17.blank? ? 1 : 0)
+ attributes["age6_known"] = age6_known?
attributes["age6"] = field_17 if attributes["age6_known"].zero? && field_17&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age7_known"] = (field_18 == "R" || field_18.blank? ? 1 : 0)
+ attributes["age7_known"] = age7_known?
attributes["age7"] = field_18 if attributes["age7_known"].zero? && field_18&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age8_known"] = (field_19 == "R" || field_19.blank? ? 1 : 0)
+ attributes["age8_known"] = age8_known?
attributes["age8"] = field_19 if attributes["age8_known"].zero? && field_19&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_20
@@ -920,13 +920,13 @@ private
attributes["ecstat7"] = field_41
attributes["ecstat8"] = field_42
- attributes["details_known_2"] = details_known(2)
- attributes["details_known_3"] = details_known(3)
- attributes["details_known_4"] = details_known(4)
- attributes["details_known_5"] = details_known(5)
- attributes["details_known_6"] = details_known(6)
- attributes["details_known_7"] = details_known(7)
- attributes["details_known_8"] = details_known(8)
+ attributes["details_known_2"] = details_known?(2)
+ attributes["details_known_3"] = details_known?(3)
+ attributes["details_known_4"] = details_known?(4)
+ attributes["details_known_5"] = details_known?(5)
+ attributes["details_known_6"] = details_known?(6)
+ attributes["details_known_7"] = details_known?(7)
+ attributes["details_known_8"] = details_known?(8)
attributes["armedforces"] = field_45
attributes["leftreg"] = leftreg
@@ -1112,7 +1112,32 @@ private
end
end
- def details_known(person_n)
+ def age1_known?
+ return 1 if field_12 == "R"
+ return 1 if field_12.blank?
+
+ 0
+ end
+
+ [
+ { person: 2, field: :field_13 },
+ { person: 3, field: :field_14 },
+ { person: 4, field: :field_15 },
+ { person: 5, field: :field_16 },
+ { person: 6, field: :field_17 },
+ { person: 7, field: :field_18 },
+ { person: 8, field: :field_19 },
+ ].each do |hash|
+ define_method("age#{hash[:person]}_known?") do
+ return 1 if public_send(hash[:field]) == "R"
+ return 0 if send("person_#{hash[:person]}_present?")
+ return 1 if public_send(hash[:field]).blank?
+
+ 0
+ end
+ end
+
+ def details_known?(person_n)
send("person_#{person_n}_present?") ? 0 : 1
end
@@ -1129,31 +1154,31 @@ private
end
def person_2_present?
- field_13.present? && field_21.present? && field_28.present?
+ field_13.present? || field_21.present? || field_28.present?
end
def person_3_present?
- field_14.present? && field_22.present? && field_29.present?
+ field_14.present? || field_22.present? || field_29.present?
end
def person_4_present?
- field_15.present? && field_23.present? && field_30.present?
+ field_15.present? || field_23.present? || field_30.present?
end
def person_5_present?
- field_16.present? && field_24.present? && field_31.present?
+ field_16.present? || field_24.present? || field_31.present?
end
def person_6_present?
- field_17.present? && field_25.present? && field_32.present?
+ field_17.present? || field_25.present? || field_32.present?
end
def person_7_present?
- field_18.present? && field_26.present? && field_33.present?
+ field_18.present? || field_26.present? || field_33.present?
end
def person_8_present?
- field_19.present? && field_27.present? && field_34.present?
+ field_19.present? || field_27.present? || field_34.present?
end
def tshortfall_known
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index 3c214a204..d1689b2dd 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -805,28 +805,28 @@ private
attributes["tenancylength"] = field_43
attributes["declaration"] = field_45
- attributes["age1_known"] = (field_46 == "R" || field_46.blank? ? 1 : 0)
+ attributes["age1_known"] = age1_known?
attributes["age1"] = field_46 if attributes["age1_known"].zero? && field_46&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age2_known"] = (field_52 == "R" || field_52.blank? ? 1 : 0)
+ attributes["age2_known"] = age2_known?
attributes["age2"] = field_52 if attributes["age2_known"].zero? && field_52&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age3_known"] = (field_56 == "R" || field_56.blank? ? 1 : 0)
+ attributes["age3_known"] = age3_known?
attributes["age3"] = field_56 if attributes["age3_known"].zero? && field_56&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age4_known"] = (field_60 == "R" || field_60.blank? ? 1 : 0)
+ attributes["age4_known"] = age4_known?
attributes["age4"] = field_60 if attributes["age4_known"].zero? && field_60&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age5_known"] = (field_64 == "R" || field_64.blank? ? 1 : 0)
+ attributes["age5_known"] = age5_known?
attributes["age5"] = field_64 if attributes["age5_known"].zero? && field_64&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age6_known"] = (field_68 == "R" || field_68.blank? ? 1 : 0)
+ attributes["age6_known"] = age6_known?
attributes["age6"] = field_68 if attributes["age6_known"].zero? && field_68&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age7_known"] = (field_72 == "R" || field_72.blank? ? 1 : 0)
+ attributes["age7_known"] = age7_known?
attributes["age7"] = field_72 if attributes["age7_known"].zero? && field_72&.match(/\A\d{1,3}\z|\AR\z/)
- attributes["age8_known"] = (field_76 == "R" || field_76.blank? ? 1 : 0)
+ attributes["age8_known"] = age8_known?
attributes["age8"] = field_76 if attributes["age8_known"].zero? && field_76&.match(/\A\d{1,3}\z|\AR\z/)
attributes["sex1"] = field_47
@@ -859,13 +859,13 @@ private
attributes["ecstat7"] = field_74
attributes["ecstat8"] = field_78
- attributes["details_known_2"] = details_known(2)
- attributes["details_known_3"] = details_known(3)
- attributes["details_known_4"] = details_known(4)
- attributes["details_known_5"] = details_known(5)
- attributes["details_known_6"] = details_known(6)
- attributes["details_known_7"] = details_known(7)
- attributes["details_known_8"] = details_known(8)
+ attributes["details_known_2"] = details_known?(2)
+ attributes["details_known_3"] = details_known?(3)
+ attributes["details_known_4"] = details_known?(4)
+ attributes["details_known_5"] = details_known?(5)
+ attributes["details_known_6"] = details_known?(6)
+ attributes["details_known_7"] = details_known?(7)
+ attributes["details_known_8"] = details_known?(8)
attributes["armedforces"] = field_79
attributes["leftreg"] = leftreg
@@ -1077,36 +1077,61 @@ private
end
end
- def details_known(person_n)
+ def age1_known?
+ return 1 if field_46 == "R"
+ return 1 if field_46.blank?
+
+ 0
+ end
+
+ [
+ { person: 2, field: :field_52 },
+ { person: 3, field: :field_56 },
+ { person: 4, field: :field_60 },
+ { person: 5, field: :field_64 },
+ { person: 6, field: :field_68 },
+ { person: 7, field: :field_72 },
+ { person: 8, field: :field_76 },
+ ].each do |hash|
+ define_method("age#{hash[:person]}_known?") do
+ return 1 if public_send(hash[:field]) == "R"
+ return 0 if send("person_#{hash[:person]}_present?")
+ return 1 if public_send(hash[:field]).blank?
+
+ 0
+ end
+ end
+
+ def details_known?(person_n)
send("person_#{person_n}_present?") ? 0 : 1
end
def person_2_present?
- field_51.present? && field_52.present? && field_53.present?
+ field_51.present? || field_52.present? || field_53.present?
end
def person_3_present?
- field_55.present? && field_56.present? && field_57.present?
+ field_55.present? || field_56.present? || field_57.present?
end
def person_4_present?
- field_59.present? && field_60.present? && field_61.present?
+ field_59.present? || field_60.present? || field_61.present?
end
def person_5_present?
- field_63.present? && field_64.present? && field_65.present?
+ field_63.present? || field_64.present? || field_65.present?
end
def person_6_present?
- field_67.present? && field_68.present? && field_69.present?
+ field_67.present? || field_68.present? || field_69.present?
end
def person_7_present?
- field_71.present? && field_72.present? && field_73.present?
+ field_71.present? || field_72.present? || field_73.present?
end
def person_8_present?
- field_75.present? && field_76.present? && field_77.present?
+ field_75.present? || field_76.present? || field_77.present?
end
def leftreg
diff --git a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
index 29c48006e..bada35dad 100644
--- a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
@@ -446,6 +446,16 @@ RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
end
end
+ describe "#field_14" do # age3
+ context "when blank but gender given" do
+ let(:attributes) { valid_attributes.merge(field_14: "", field_22: "F") }
+
+ it "returns an error" do
+ expect(parser.errors[:field_14]).to be_present
+ end
+ end
+ end
+
describe "#field_52" do # leaving reason
context "when field_134 is 1 meaning it is a renewal" do
context "when field_52 is 40" do
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 1bb4dc99a..7dc1e177b 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -733,6 +733,16 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
end
end
+
+ describe "#field_56" do # age3
+ context "when null but gender given" do
+ let(:attributes) { setup_section_params.merge({ field_56: "", field_57: "F" }) }
+
+ it "returns an error" do
+ expect(parser.errors[:field_56]).to be_present
+ end
+ end
+ end
end
describe "#log" do
From 5aba3ef9a966ffffce13cd5438ddd4c0727f842d Mon Sep 17 00:00:00 2001
From: Jack <113976590+bibblobcode@users.noreply.github.com>
Date: Mon, 27 Mar 2023 09:01:39 +0100
Subject: [PATCH 28/31] Run rent validations when >= 4 beds (#1465)
---
app/models/validations/financial_validations.rb | 11 +++++++++--
spec/models/validations/financial_validations_spec.rb | 8 ++++----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb
index f39c17af7..fc1c44585 100644
--- a/app/models/validations/financial_validations.rb
+++ b/app/models/validations/financial_validations.rb
@@ -188,7 +188,12 @@ private
collection_year = record.collection_start_year
- rent_range = LaRentRange.find_by(start_year: collection_year, la: record.la, beds: record.beds_for_la_rent_range, lettype: record.lettype)
+ rent_range = LaRentRange.find_by(
+ start_year: collection_year,
+ la: record.la,
+ beds: record.beds_for_la_rent_range,
+ lettype: record.lettype,
+ )
if rent_range.present? && !weekly_value_in_range(record, "brent", rent_range.hard_min, rent_range.hard_max) && record.brent.present? && record.period.present?
if record.weekly_value(record["brent"]) < rent_range.hard_min
@@ -201,7 +206,9 @@ private
record.errors.add :rent_type, I18n.t("validations.financial.brent.rent_type.below_hard_min")
record.errors.add :needstype, I18n.t("validations.financial.brent.needstype.below_hard_min")
record.errors.add :period, I18n.t("validations.financial.brent.period.below_hard_min")
- elsif record.beds.blank? || record.beds < LaRentRange::MAX_BEDS
+ end
+
+ if record.weekly_value(record["brent"]) > rent_range.hard_max
record.errors.add :brent, I18n.t("validations.financial.brent.above_hard_max")
record.errors.add :beds, I18n.t("validations.financial.brent.beds.above_hard_max")
record.errors.add :la, I18n.t("validations.financial.brent.la.above_hard_max")
diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb
index 1f40f7cbc..8cb777029 100644
--- a/spec/models/validations/financial_validations_spec.rb
+++ b/spec/models/validations/financial_validations_spec.rb
@@ -788,7 +788,7 @@ RSpec.describe Validations::FinancialValidations do
LaRentRange.create!(
ranges_rent_id: "1",
la: "E07000223",
- beds: 1,
+ beds: 4,
lettype: 1,
soft_min: 12.41,
soft_max: 89.54,
@@ -814,7 +814,7 @@ RSpec.describe Validations::FinancialValidations do
record.lettype = 1
record.period = 1
record.la = "E07000223"
- record.beds = 1
+ record.beds = 4
record.startdate = Time.zone.local(2021, 9, 17)
record.brent = 9.17
@@ -846,7 +846,7 @@ RSpec.describe Validations::FinancialValidations do
record.lettype = 1
record.period = 1
record.la = "E07000223"
- record.beds = 1
+ record.beds = 4
record.startdate = Time.zone.local(2021, 9, 17)
record.brent = 200
@@ -883,7 +883,7 @@ RSpec.describe Validations::FinancialValidations do
record.period = 1
record.la = "E07000223"
record.startdate = Time.zone.local(2022, 2, 5)
- record.beds = 1
+ record.beds = 4
record.brent = 200
financial_validator.validate_rent_amount(record)
From be6e6585bb82c19218f6d380776061794d0958a1 Mon Sep 17 00:00:00 2001
From: Phil Lee
Date: Mon, 27 Mar 2023 09:40:43 +0100
Subject: [PATCH 29/31] bulk upload maps new field errors (#1471)
---
.../lettings/year2023/row_parser.rb | 6 +++++
.../lettings/year2023/row_parser_spec.rb | 23 ++++++++++++++++++-
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb
index d1689b2dd..2fc61921f 100644
--- a/app/services/bulk_upload/lettings/year2023/row_parser.rb
+++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb
@@ -766,6 +766,12 @@ private
mrcdate: %i[field_36 field_37 field_38],
voiddate: %i[field_33 field_34 field_35],
+
+ uprn: [:field_18],
+ address_line1: [:field_19],
+ address_line2: [:field_20],
+ town_or_city: [:field_21],
+ county: [:field_22],
}
end
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index 7dc1e177b..bc35388d7 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -63,8 +63,19 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\", \"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {})
+ body = {
+ results: [
+ {
+ DPA: {
+ "POSTCODE": "EC1N 2TD",
+ "POST_TOWN": "Newcastle",
+ },
+ },
+ ],
+ }.to_json
+
stub_request(:get, "https://api.os.uk/search/places/v1/uprn?key=OS_DATA_KEY&uprn=100023336956")
- .to_return(status: 200, body: "{}", headers: {})
+ .to_return(status: 200, body:, headers: {})
parser.valid?
end
@@ -712,6 +723,16 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
end
+ describe "#field_18" do # UPRN
+ context "when over 12 characters" do
+ let(:attributes) { { bulk_upload:, field_18: "1234567890123" } }
+
+ it "has errors on the field" do
+ expect(parser.errors[:field_18]).to be_present
+ end
+ end
+ end
+
describe "#field_30" do
context "when null" do
let(:attributes) { setup_section_params.merge({ field_30: nil }) }
From bc722ab1ff2a9d34bd4f2571803695892c554be8 Mon Sep 17 00:00:00 2001
From: Jack <113976590+bibblobcode@users.noreply.github.com>
Date: Mon, 27 Mar 2023 10:28:41 +0100
Subject: [PATCH 30/31] British Summer Time fixes (#1473)
---
spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb | 2 +-
spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
index bada35dad..b771cbcea 100644
--- a/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2022/row_parser_spec.rb
@@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe BulkUpload::Lettings::Year2022::RowParser do
subject(:parser) { described_class.new(attributes) }
- let(:now) { Time.zone.today }
+ let(:now) { Time.zone.parse("01/03/2023") }
let(:attributes) { { bulk_upload: } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
index bc35388d7..a7dc629c0 100644
--- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
+++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
@@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
subject(:parser) { described_class.new(attributes) }
- let(:now) { Time.zone.today }
+ let(:now) { Time.zone.parse("01/03/2023") }
let(:attributes) { { bulk_upload: } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: nil) }
From b5c2584a6e4a042e12f488626cf4723d95da93cf Mon Sep 17 00:00:00 2001
From: natdeanlewissoftwire
<94526761+natdeanlewissoftwire@users.noreply.github.com>
Date: Mon, 27 Mar 2023 14:44:53 +0100
Subject: [PATCH 31/31] CLDC-1854 Make schemes with 0 locations be incomplete
rather than active (#1456)
* feat: update scheme status so incomplete unless has active locations
* feat: change active -> completed
* feat: change to confirmed to add clarification in code
* feat: fix tests
* refactor: rubocop
* feat: add tests for incomplete schemes
* refactor: linting
* refactor: simplify
---
app/models/location.rb | 1 +
app/models/scheme.rb | 2 +-
spec/helpers/schemes_helper_spec.rb | 273 ++++++++++--------
spec/models/scheme_spec.rb | 1 +
.../validations/date_validations_spec.rb | 2 +
.../validations/setup_validations_spec.rb | 2 +
spec/requests/schemes_controller_spec.rb | 7 +
7 files changed, 174 insertions(+), 114 deletions(-)
diff --git a/app/models/location.rb b/app/models/location.rb
index 48689ef71..6050a05cf 100644
--- a/app/models/location.rb
+++ b/app/models/location.rb
@@ -23,6 +23,7 @@ class Location < ApplicationRecord
scope :search_by, ->(param) { search_by_name(param).or(search_by_postcode(param)) }
scope :started, -> { where("startdate <= ?", Time.zone.today).or(where(startdate: nil)) }
scope :active, -> { where(confirmed: true).and(started) }
+ scope :confirmed, -> { where(confirmed: true) }
LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h
diff --git a/app/models/scheme.rb b/app/models/scheme.rb
index ca3624e3a..1ab65ea32 100644
--- a/app/models/scheme.rb
+++ b/app/models/scheme.rb
@@ -235,7 +235,7 @@ class Scheme < ApplicationRecord
end
def status_at(date)
- return :incomplete unless confirmed
+ return :incomplete unless confirmed && locations.confirmed.any?
return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date
return :reactivating_soon if recent_deactivation&.reactivation_date.present? && date < recent_deactivation.reactivation_date
diff --git a/spec/helpers/schemes_helper_spec.rb b/spec/helpers/schemes_helper_spec.rb
index 77f178f62..6ab283eca 100644
--- a/spec/helpers/schemes_helper_spec.rb
+++ b/spec/helpers/schemes_helper_spec.rb
@@ -110,166 +110,213 @@ RSpec.describe SchemesHelper do
let(:support_user) { FactoryBot.create(:user, :support) }
let(:coordinator_user) { FactoryBot.create(:user, :data_coordinator) }
- it "returns correct display attributes for a support user" do
- attributes = [
- { name: "Scheme code", value: "S#{scheme.id}" },
- { name: "Name", value: "Test service_name", edit: true },
- { name: "Confidential information", value: "No", edit: true },
- { name: "Type of scheme", value: "Housing for older people" },
- { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
- { name: "Housing stock owned by", value: "Acme LTD Owning", edit: true },
- { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
- { name: "Primary client group", value: "Rough sleepers" },
- { name: "Has another client group", value: "Yes" },
- { name: "Secondary client group", value: "Refugees (permanent)" },
- { name: "Level of support given", value: "High level" },
- { name: "Intended length of stay", value: "Permanent" },
- { name: "Availability", value: "Active from 1 April 2022" },
- { name: "Status", value: status_tag(:active) },
- ]
- expect(display_scheme_attributes(scheme, support_user)).to eq(attributes)
- end
+ context "when scheme has no locations" do
+ it "returns correct display attributes for a support user" do
+ attributes = [
+ { name: "Scheme code", value: "S#{scheme.id}" },
+ { name: "Name", value: "Test service_name", edit: true },
+ { name: "Confidential information", value: "No", edit: true },
+ { name: "Type of scheme", value: "Housing for older people" },
+ { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
+ { name: "Housing stock owned by", value: "Acme LTD Owning", edit: true },
+ { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
+ { name: "Primary client group", value: "Rough sleepers" },
+ { name: "Has another client group", value: "Yes" },
+ { name: "Secondary client group", value: "Refugees (permanent)" },
+ { name: "Level of support given", value: "High level" },
+ { name: "Intended length of stay", value: "Permanent" },
+ { name: "Availability", value: "Active from 1 April 2022" },
+ { name: "Status", value: status_tag(:incomplete) },
+ ]
+ expect(display_scheme_attributes(scheme, support_user)).to eq(attributes)
+ end
- it "returns correct display attributes for a coordinator user" do
- attributes = [
- { name: "Scheme code", value: "S#{scheme.id}" },
- { name: "Name", value: "Test service_name", edit: true },
- { name: "Confidential information", value: "No", edit: true },
- { name: "Type of scheme", value: "Housing for older people" },
- { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
- { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
- { name: "Primary client group", value: "Rough sleepers" },
- { name: "Has another client group", value: "Yes" },
- { name: "Secondary client group", value: "Refugees (permanent)" },
- { name: "Level of support given", value: "High level" },
- { name: "Intended length of stay", value: "Permanent" },
- { name: "Availability", value: "Active from 1 April 2022" },
- { name: "Status", value: status_tag(:active) },
- ]
- expect(display_scheme_attributes(scheme, coordinator_user)).to eq(attributes)
+ it "returns correct display attributes for a coordinator user" do
+ attributes = [
+ { name: "Scheme code", value: "S#{scheme.id}" },
+ { name: "Name", value: "Test service_name", edit: true },
+ { name: "Confidential information", value: "No", edit: true },
+ { name: "Type of scheme", value: "Housing for older people" },
+ { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
+ { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
+ { name: "Primary client group", value: "Rough sleepers" },
+ { name: "Has another client group", value: "Yes" },
+ { name: "Secondary client group", value: "Refugees (permanent)" },
+ { name: "Level of support given", value: "High level" },
+ { name: "Intended length of stay", value: "Permanent" },
+ { name: "Availability", value: "Active from 1 April 2022" },
+ { name: "Status", value: status_tag(:incomplete) },
+ ]
+ expect(display_scheme_attributes(scheme, coordinator_user)).to eq(attributes)
+ end
end
- context "when the scheme toggle is disabled" do
- it "doesn't show the scheme status" do
- allow(FeatureToggle).to receive(:scheme_toggle_enabled?).and_return(false)
- attributes = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Status" }
- expect(attributes).to be_nil
+ context "when scheme has a location" do
+ before do
+ FactoryBot.create(:location, scheme:)
end
- end
- context "when the managing organisation is the owning organisation" do
- it "doesn't show the organisation providing support" do
- attributes = display_scheme_attributes(scheme_where_managing_organisation_is_owning_organisation, support_user).find { |x| x[:name] == "Organisation providing support" }
- expect(attributes).to be_nil
+ it "returns correct display attributes for a support user" do
+ attributes = [
+ { name: "Scheme code", value: "S#{scheme.id}" },
+ { name: "Name", value: "Test service_name", edit: true },
+ { name: "Confidential information", value: "No", edit: true },
+ { name: "Type of scheme", value: "Housing for older people" },
+ { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
+ { name: "Housing stock owned by", value: "Acme LTD Owning", edit: true },
+ { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
+ { name: "Primary client group", value: "Rough sleepers" },
+ { name: "Has another client group", value: "Yes" },
+ { name: "Secondary client group", value: "Refugees (permanent)" },
+ { name: "Level of support given", value: "High level" },
+ { name: "Intended length of stay", value: "Permanent" },
+ { name: "Availability", value: "Active from 1 April 2022" },
+ { name: "Status", value: status_tag(:active) },
+ ]
+ expect(display_scheme_attributes(scheme, support_user)).to eq(attributes)
end
- end
- context "when viewing availability" do
- context "with no deactivations" do
- it "displays created_at as availability date" do
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+ it "returns correct display attributes for a coordinator user" do
+ attributes = [
+ { name: "Scheme code", value: "S#{scheme.id}" },
+ { name: "Name", value: "Test service_name", edit: true },
+ { name: "Confidential information", value: "No", edit: true },
+ { name: "Type of scheme", value: "Housing for older people" },
+ { name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
+ { name: "Support services provided by", value: "A registered charity or voluntary organisation" },
+ { name: "Primary client group", value: "Rough sleepers" },
+ { name: "Has another client group", value: "Yes" },
+ { name: "Secondary client group", value: "Refugees (permanent)" },
+ { name: "Level of support given", value: "High level" },
+ { name: "Intended length of stay", value: "Permanent" },
+ { name: "Availability", value: "Active from 1 April 2022" },
+ { name: "Status", value: status_tag(:active) },
+ ]
+ expect(display_scheme_attributes(scheme, coordinator_user)).to eq(attributes)
+ end
- expect(availability_attribute).to eq("Active from #{scheme.created_at.to_formatted_s(:govuk_date)}")
+ context "when the scheme toggle is disabled" do
+ it "doesn't show the scheme status" do
+ allow(FeatureToggle).to receive(:scheme_toggle_enabled?).and_return(false)
+ attributes = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Status" }
+ expect(attributes).to be_nil
end
+ end
- it "displays current collection start date as availability date if created_at is later than collection start date" do
- scheme.update!(created_at: Time.zone.local(2022, 4, 16))
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
-
- expect(availability_attribute).to eq("Active from 1 April 2022")
+ context "when the managing organisation is the owning organisation" do
+ it "doesn't show the organisation providing support" do
+ attributes = display_scheme_attributes(scheme_where_managing_organisation_is_owning_organisation, support_user).find { |x| x[:name] == "Organisation providing support" }
+ expect(attributes).to be_nil
end
end
- context "with previous deactivations" do
- context "and all reactivated deactivations" do
- before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
- scheme.reload
+ context "when viewing availability" do
+ context "with no deactivations" do
+ it "displays created_at as availability date" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+
+ expect(availability_attribute).to eq("Active from #{scheme.created_at.to_formatted_s(:govuk_date)}")
end
- it "displays the timeline of availability" do
+ it "displays current collection start date as availability date if created_at is later than collection start date" do
+ scheme.update!(created_at: Time.zone.local(2022, 4, 16))
availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
- expect(availability_attribute).to eq("Active from 1 April 2022 to 9 August 2022\nDeactivated on 10 August 2022\nActive from 1 September 2022 to 14 September 2022\nDeactivated on 15 September 2022\nActive from 28 September 2022")
+ expect(availability_attribute).to eq("Active from 1 April 2022")
end
end
- context "and non reactivated deactivation" do
- before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil, scheme:)
- scheme.reload
+ context "with previous deactivations" do
+ context "and all reactivated deactivations" do
+ before do
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
+ scheme.reload
+ end
+
+ it "displays the timeline of availability" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 9 August 2022\nDeactivated on 10 August 2022\nActive from 1 September 2022 to 14 September 2022\nDeactivated on 15 September 2022\nActive from 28 September 2022")
+ end
end
- it "displays the timeline of availability" do
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+ context "and non reactivated deactivation" do
+ before do
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil, scheme:)
+ scheme.reload
+ end
+
+ it "displays the timeline of availability" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
- expect(availability_attribute).to eq("Active from 1 April 2022 to 9 August 2022\nDeactivated on 10 August 2022\nActive from 1 September 2022 to 14 September 2022\nDeactivated on 15 September 2022")
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 9 August 2022\nDeactivated on 10 August 2022\nActive from 1 September 2022 to 14 September 2022\nDeactivated on 15 September 2022")
+ end
end
end
- end
- context "with out of order deactivations" do
- context "and all reactivated deactivations" do
- before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: Time.zone.local(2022, 6, 18), scheme:)
- scheme.reload
+ context "with out of order deactivations" do
+ context "and all reactivated deactivations" do
+ before do
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: Time.zone.local(2022, 6, 18), scheme:)
+ scheme.reload
+ end
+
+ it "displays the timeline of availability" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 18 June 2022 to 23 September 2022\nDeactivated on 24 September 2022\nActive from 28 September 2022")
+ end
end
- it "displays the timeline of availability" do
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+ context "and one non reactivated deactivation" do
+ before do
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, scheme:)
+ scheme.reload
+ end
+
+ it "displays the timeline of availability" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
- expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 18 June 2022 to 23 September 2022\nDeactivated on 24 September 2022\nActive from 28 September 2022")
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 28 September 2022")
+ end
end
end
- context "and one non reactivated deactivation" do
- before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, scheme:)
- scheme.reload
- end
+ context "with multiple out of order deactivations" do
+ context "and one non reactivated deactivation" do
+ before do
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 24), reactivation_date: Time.zone.local(2022, 10, 28), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, scheme:)
+ scheme.reload
+ end
- it "displays the timeline of availability" do
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
+ it "displays the timeline of availability" do
+ availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
- expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 28 September 2022")
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 28 September 2022 to 23 October 2022\nDeactivated on 24 October 2022\nActive from 28 October 2022")
+ end
end
end
- end
- context "with multiple out of order deactivations" do
- context "and one non reactivated deactivation" do
+ context "with intersecting deactivations" do
before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 24), reactivation_date: Time.zone.local(2022, 10, 28), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 10), reactivation_date: Time.zone.local(2022, 12, 1), scheme:)
+ FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 11, 11), reactivation_date: Time.zone.local(2022, 12, 11), scheme:)
scheme.reload
end
it "displays the timeline of availability" do
availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
- expect(availability_attribute).to eq("Active from 1 April 2022 to 14 June 2022\nDeactivated on 15 June 2022\nActive from 28 September 2022 to 23 October 2022\nDeactivated on 24 October 2022\nActive from 28 October 2022")
+ expect(availability_attribute).to eq("Active from 1 April 2022 to 9 October 2022\nDeactivated on 10 October 2022\nActive from 11 December 2022")
end
end
end
-
- context "with intersecting deactivations" do
- before do
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 10), reactivation_date: Time.zone.local(2022, 12, 1), scheme:)
- FactoryBot.create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 11, 11), reactivation_date: Time.zone.local(2022, 12, 11), scheme:)
- scheme.reload
- end
-
- it "displays the timeline of availability" do
- availability_attribute = display_scheme_attributes(scheme, support_user).find { |x| x[:name] == "Availability" }[:value]
-
- expect(availability_attribute).to eq("Active from 1 April 2022 to 9 October 2022\nDeactivated on 10 October 2022\nActive from 11 December 2022")
- end
- end
end
end
end
diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb
index f59fe56c5..db824d7cd 100644
--- a/spec/models/scheme_spec.rb
+++ b/spec/models/scheme_spec.rb
@@ -96,6 +96,7 @@ RSpec.describe Scheme, type: :model do
let(:scheme) { FactoryBot.build(:scheme) }
before do
+ FactoryBot.create(:location, scheme:)
Timecop.freeze(2022, 6, 7)
end
diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb
index 410da4f0c..18912b1c8 100644
--- a/spec/models/validations/date_validations_spec.rb
+++ b/spec/models/validations/date_validations_spec.rb
@@ -165,6 +165,7 @@ RSpec.describe Validations::DateValidations do
let(:scheme) { create(:scheme) }
before do
+ FactoryBot.create(:location, scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:)
scheme.reload
end
@@ -189,6 +190,7 @@ RSpec.describe Validations::DateValidations do
let(:scheme) { create(:scheme) }
before do
+ FactoryBot.create(:location, scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 2), reactivation_date: Time.zone.local(2022, 8, 3), scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 1), reactivation_date: Time.zone.local(2022, 9, 4), scheme:)
diff --git a/spec/models/validations/setup_validations_spec.rb b/spec/models/validations/setup_validations_spec.rb
index 69e22f1e2..16d52fb07 100644
--- a/spec/models/validations/setup_validations_spec.rb
+++ b/spec/models/validations/setup_validations_spec.rb
@@ -188,6 +188,7 @@ RSpec.describe Validations::SetupValidations do
let(:scheme) { create(:scheme, created_at: Time.zone.local(2022, 4, 1)) }
before do
+ FactoryBot.create(:location, scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:)
scheme.reload
end
@@ -212,6 +213,7 @@ RSpec.describe Validations::SetupValidations do
let(:scheme) { create(:scheme, created_at: Time.zone.local(2022, 4, 1)) }
before do
+ FactoryBot.create(:location, scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 2), reactivation_date: Time.zone.local(2022, 8, 3), scheme:)
create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 1), reactivation_date: Time.zone.local(2022, 9, 4), scheme:)
diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb
index 431270767..fb9150940 100644
--- a/spec/requests/schemes_controller_spec.rb
+++ b/spec/requests/schemes_controller_spec.rb
@@ -7,6 +7,12 @@ RSpec.describe SchemesController, type: :request do
let(:user) { FactoryBot.create(:user, :support) }
let!(:schemes) { FactoryBot.create_list(:scheme, 5) }
+ before do
+ schemes.each do |scheme|
+ FactoryBot.create(:location, scheme:)
+ end
+ end
+
describe "#index" do
context "when not signed in" do
it "redirects to the sign in page" do
@@ -260,6 +266,7 @@ RSpec.describe SchemesController, type: :request do
let(:add_deactivations) { scheme.scheme_deactivation_periods << scheme_deactivation_period }
before do
+ FactoryBot.create(:location, scheme:)
Timecop.freeze(Time.utc(2022, 10, 10))
sign_in user
add_deactivations