Browse Source

CLDC-1916 Validate this and next year start date in saleslogs

pull/1317/head
Jack S 3 years ago
parent
commit
d86518f4df
  1. 4
      app/helpers/collection_time_helper.rb
  2. 21
      app/helpers/tasklist_helper.rb
  3. 37
      app/models/validations/sales/setup_validations.rb
  4. 4
      config/initializers/feature_toggle.rb
  5. 6
      config/locales/en.yml
  6. 142
      spec/helpers/tasklist_helper_spec.rb
  7. 96
      spec/models/validations/sales/setup_validations_spec.rb

4
app/helpers/collection_time_helper.rb

@ -24,6 +24,10 @@ module CollectionTimeHelper
Time.zone.local(current_collection_start_year + 1, 3, 31) Time.zone.local(current_collection_start_year + 1, 3, 31)
end end
def next_collection_end_date
current_collection_end_date + 1.year
end
def next_collection_start_year def next_collection_start_year
current_collection_start_year + 1 current_collection_start_year + 1
end end

21
app/helpers/tasklist_helper.rb

@ -11,15 +11,6 @@ module TasklistHelper
log.form.subsections.count { |subsection| subsection.status(log) == status && subsection.applicable_questions(log).count.positive? } log.form.subsections.count { |subsection| subsection.status(log) == status && subsection.applicable_questions(log).count.positive? }
end end
def next_page_or_check_answers(subsection, log, current_user)
path = if subsection.is_started?(log)
"#{log.class.name.underscore}_#{subsection.id}_check_answers_path"
else
"#{log.class.name.underscore}_#{next_question_page(subsection, log, current_user)}_path"
end
send(path, log)
end
def next_question_page(subsection, log, current_user) def next_question_page(subsection, log, current_user)
if subsection.pages.first.routed_to?(log, current_user) if subsection.pages.first.routed_to?(log, current_user)
subsection.pages.first.id subsection.pages.first.id
@ -46,4 +37,16 @@ module TasklistHelper
"This log is from the #{log.form.start_date.year}/#{log.form.start_date.year + 1} collection window, which is now closed." "This log is from the #{log.form.start_date.year}/#{log.form.start_date.year + 1} collection window, which is now closed."
end end
end end
private
def next_page_or_check_answers(subsection, log, current_user)
path = if subsection.is_started?(log)
"#{log.class.name.underscore}_#{subsection.id}_check_answers_path"
else
"#{log.class.name.underscore}_#{next_question_page(subsection, log, current_user)}_path"
end
send(path, log)
end
end end

37
app/models/validations/sales/setup_validations.rb

@ -1,11 +1,44 @@
module Validations::Sales::SetupValidations module Validations::Sales::SetupValidations
include Validations::SharedValidations include Validations::SharedValidations
include CollectionTimeHelper
def validate_saledate(record) def validate_saledate(record)
return unless record.saledate && date_valid?("saledate", record) return unless record.saledate && date_valid?("saledate", record)
unless record.saledate.between?(current_collection_start_date, current_collection_end_date) || !FeatureToggle.saledate_collection_window_validation_enabled? unless record.saledate.between?(current_collection_start_date, active_collection_end_date)
record.errors.add :saledate, I18n.t("validations.setup.saledate.financial_year") record.errors.add :saledate, validation_error_message
end
end
private
def active_collection_end_date
if FeatureToggle.saledate_next_collection_year_validation_enabled?
next_collection_end_date
else
current_collection_end_date
end
end
def validation_error_message
start_date = current_collection_start_date
if FeatureToggle.saledate_next_collection_year_validation_enabled?
I18n.t(
"validations.setup.saledate.current_and_next_financial_year",
current_start_year_short: start_date.strftime("%y"),
current_end_year_short: current_collection_end_date.strftime("%y"),
current_start_year_long: start_date.strftime("%Y"),
next_end_year_short: next_collection_end_date.strftime("%y"),
next_end_year_long: next_collection_end_date.strftime("%Y"),
)
else
I18n.t(
"validations.setup.saledate.current_financial_year",
current_start_year_short: start_date.strftime("%y"),
current_end_year_short: current_collection_end_date.strftime("%y"),
current_start_year_long: start_date.strftime("%Y"),
current_end_year_long: current_collection_end_date.strftime("%Y"),
)
end end
end end
end end

4
config/initializers/feature_toggle.rb

@ -7,8 +7,8 @@ class FeatureToggle
Rails.env.production? || Rails.env.test? || Rails.env.staging? Rails.env.production? || Rails.env.test? || Rails.env.staging?
end end
def self.saledate_collection_window_validation_enabled? def self.saledate_next_collection_year_validation_enabled?
Rails.env.production? || Rails.env.test? || Rails.env.staging? !Rails.env.production?
end end
def self.sales_log_enabled? def self.sales_log_enabled?

6
config/locales/en.yml

@ -150,7 +150,11 @@ en:
intermediate_rent_product_name: intermediate_rent_product_name:
blank: "Enter name of other intermediate rent product" blank: "Enter name of other intermediate rent product"
saledate: saledate:
financial_year: "Date must be from 22/23 financial year, which is between 1st April 2022 and 31st March 2023" current_financial_year:
Enter a date within the %{current_start_year_short}/%{current_end_year_short} financial year, which is between 1st April %{current_start_year_long} and 31st March %{current_end_year_long}
current_and_next_financial_year:
"Enter a date within the %{current_start_year_short}/%{current_end_year_short} or %{current_end_year_short}/%{next_end_year_short} financial years, which is between 1st April %{current_start_year_long} and 31st March %{next_end_year_long}"
startdate: startdate:
later_than_14_days_after: "The tenancy start date must not be later than 14 days from today’s date" later_than_14_days_after: "The tenancy start date must not be later than 14 days from today’s date"
before_scheme_end_date: "The tenancy start date must be before the end date for this supported housing scheme" before_scheme_end_date: "The tenancy start date must be before the end date for this supported housing scheme"

142
spec/helpers/tasklist_helper_spec.rb

@ -1,100 +1,55 @@
require "rails_helper" require "rails_helper"
RSpec.describe TasklistHelper do RSpec.describe TasklistHelper do
describe "with lettings" do let(:now) { Time.utc(2022, 6, 1) }
let(:empty_lettings_log) { FactoryBot.create(:lettings_log) }
let(:lettings_log) { FactoryBot.create(:lettings_log, :in_progress, needstype: 1) }
let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") }
context "with 2021 2022 form" do around do |example|
before do Timecop.freeze(now) do
allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) Singleton.__init__(FormHandler)
end example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
describe "get next incomplete section" do describe "with lettings" do
it "returns the first subsection name if it is not completed" do let(:empty_lettings_log) { create(:lettings_log) }
expect(get_next_incomplete_section(lettings_log).id).to eq("household_characteristics") let(:lettings_log) { create(:lettings_log, :in_progress, needstype: 1) }
end
it "returns the first subsection name if it is partially completed" do describe "get next incomplete section" do
lettings_log["tenancycode"] = 123 it "returns the first subsection name if it is not completed" do
expect(get_next_incomplete_section(lettings_log).id).to eq("household_characteristics") expect(get_next_incomplete_section(lettings_log).id).to eq("household_characteristics")
end
end end
describe "get sections count" do it "returns the first subsection name if it is partially completed" do
it "returns the total of sections if no status is given" do lettings_log["tenancycode"] = 123
expect(get_subsections_count(empty_lettings_log)).to eq(8) expect(get_next_incomplete_section(lettings_log).id).to eq("household_characteristics")
end
it "returns 0 sections for completed sections if no sections are completed" do
expect(get_subsections_count(empty_lettings_log, :completed)).to eq(0)
end
it "returns the number of not started sections" do
expect(get_subsections_count(empty_lettings_log, :not_started)).to eq(8)
end
it "returns the number of sections in progress" do
expect(get_subsections_count(lettings_log, :in_progress)).to eq(3)
end
it "returns 0 for invalid state" do
expect(get_subsections_count(lettings_log, :fake)).to eq(0)
end
end end
end
describe "get_next_page_or_check_answers" do describe "get sections count" do
let(:subsection) { lettings_log.form.get_subsection("household_characteristics") } it "returns the total of sections if no status is given" do
let(:user) { FactoryBot.build(:user) } expect(get_subsections_count(empty_lettings_log)).to eq(1)
it "returns the check answers page path if the section has been started already" do
expect(next_page_or_check_answers(subsection, lettings_log, user)).to match(/check-answers/)
end
it "returns the first question page path for the section if it has not been started yet" do
expect(next_page_or_check_answers(subsection, empty_lettings_log, user)).to match(/tenant-code-test/)
end
it "when first question being not routed to returns the next routed question link" do
empty_lettings_log.housingneeds_a = "No"
expect(next_page_or_check_answers(subsection, empty_lettings_log, user)).to match(/person-1-gender/)
end
end end
describe "subsection link" do it "returns 0 sections for completed sections if no sections are completed" do
let(:subsection) { lettings_log.form.get_subsection("household_characteristics") } expect(get_subsections_count(empty_lettings_log, :completed)).to eq(0)
let(:user) { FactoryBot.build(:user) } end
context "with a subsection that's enabled" do
it "returns the subsection link url" do
expect(subsection_link(subsection, lettings_log, user)).to match(/household-characteristics/)
end
end
context "with a subsection that cannot be started yet" do it "returns the number of not started sections" do
before do expect(get_subsections_count(empty_lettings_log, :not_started)).to eq(1)
allow(subsection).to receive(:status).with(lettings_log).and_return(:cannot_start_yet) end
end
it "returns the label instead of a link" do it "returns the number of sections in progress" do
expect(subsection_link(subsection, lettings_log, user)).to match(subsection.label) expect(get_subsections_count(lettings_log, :in_progress)).to eq(3)
end
end
end end
end
end
describe "#review_log_text" do it "returns 0 for invalid state" do
around do |example| expect(get_subsections_count(lettings_log, :fake)).to eq(0)
Timecop.freeze(now) do
Singleton.__init__(FormHandler)
example.run
end end
Singleton.__init__(FormHandler)
end end
context "with lettings log" do describe "review_log_text" do
context "when collection_period_open? == true" do context "when collection_period_open? == true" do
context "with 2023 deadline" do context "with 2023 deadline" do
let(:now) { Time.utc(2022, 6, 1) } let(:now) { Time.utc(2022, 6, 1) }
@ -129,6 +84,29 @@ RSpec.describe TasklistHelper do
end end
end end
describe "subsection link" do
let(:subsection) { lettings_log.form.get_subsection("household_characteristics") }
let(:user) { build(:user) }
context "with a subsection that's enabled" do
it "returns the subsection link url" do
expect(subsection_link(subsection, lettings_log, user)).to match(/household-characteristics/)
end
end
context "with a subsection that cannot be started yet" do
before do
allow(subsection).to receive(:status).with(lettings_log).and_return(:cannot_start_yet)
end
it "returns the label instead of a link" do
expect(subsection_link(subsection, lettings_log, user)).to match(subsection.label)
end
end
end
end
describe "#review_log_text" do
context "with sales log" do context "with sales log" do
context "when collection_period_open? == true" do context "when collection_period_open? == true" do
let(:now) { Time.utc(2022, 6, 1) } let(:now) { Time.utc(2022, 6, 1) }
@ -142,11 +120,13 @@ RSpec.describe TasklistHelper do
end end
context "when collection_period_open? == false" do context "when collection_period_open? == false" do
let(:now) { Time.utc(2023, 7, 8) } let(:now) { Time.utc(2022, 6, 1) }
let(:sales_log) { create(:sales_log, :completed, saledate: Time.utc(2023, 2, 8)) } let!(:sales_log) { create(:sales_log, :completed) }
it "returns relevant text" do it "returns relevant text" do
expect(review_log_text(sales_log)).to eq("This log is from the 2022/2023 collection window, which is now closed.") Timecop.freeze(now + 1.year) do
expect(review_log_text(sales_log)).to eq("This log is from the 2021/2022 collection window, which is now closed.")
end
end end
end end
end end

96
spec/models/validations/sales/setup_validations_spec.rb

@ -6,43 +6,95 @@ RSpec.describe Validations::Sales::SetupValidations do
let(:validator_class) { Class.new { include Validations::Sales::SetupValidations } } let(:validator_class) { Class.new { include Validations::Sales::SetupValidations } }
describe "#validate_saledate" do describe "#validate_saledate" do
context "when saledate is blank" do context "with saledate_next_collection_year_validation_enabled == true" do
let(:record) { FactoryBot.build(:sales_log, saledate: nil) } before do
allow(FeatureToggle).to receive(:saledate_next_collection_year_validation_enabled?).and_return(true)
end
context "when saledate is blank" do
let(:record) { build(:sales_log, saledate: nil) }
it "does not add an error" do it "does not add an error" do
setup_validator.validate_saledate(record) setup_validator.validate_saledate(record)
expect(record.errors).to be_empty expect(record.errors).to be_empty
end
end end
end
context "when saledate is in the 22/23 financial year" do context "when saledate is in the 22/23 financial year" do
let(:record) { FactoryBot.build(:sales_log, saledate: Time.zone.local(2023, 1, 1)) } let(:record) { build(:sales_log, saledate: Time.zone.local(2023, 1, 1)) }
it "does not add an error" do it "does not add an error" do
setup_validator.validate_saledate(record) setup_validator.validate_saledate(record)
expect(record.errors).to be_empty expect(record.errors).to be_empty
end
end end
end
context "when saledate is before the 22/23 financial year" do context "when saledate is before the 22/23 financial year" do
let(:record) { FactoryBot.build(:sales_log, saledate: Time.zone.local(2022, 1, 1)) } let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 1, 1)) }
it "adds error" do it "adds error" do
setup_validator.validate_saledate(record) setup_validator.validate_saledate(record)
expect(record.errors[:saledate]).to include(I18n.t("validations.setup.saledate.financial_year")) expect(record.errors[:saledate]).to include("Enter a date within the 22/23 or 23/24 financial years, which is between 1st April 2022 and 31st March 2024")
end
end
context "when saledate is after the 22/23 financial year" do
let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) }
it "adds error" do
setup_validator.validate_saledate(record)
expect(record.errors[:saledate]).to include("Enter a date within the 22/23 or 23/24 financial years, which is between 1st April 2022 and 31st March 2024")
end
end end
end end
context "when saledate is after the 22/23 financial year" do context "with saledate_next_collection_year_validation_enabled == false" do
let(:record) { FactoryBot.build(:sales_log, saledate: Time.zone.local(2023, 4, 1)) } before do
allow(FeatureToggle).to receive(:saledate_next_collection_year_validation_enabled?).and_return(false)
end
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)
expect(record.errors).to be_empty
end
end
context "when saledate is in the 22/23 financial year" 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)
expect(record.errors).to be_empty
end
end
context "when saledate is before the 22/23 financial year" do
let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 1, 1)) }
it "adds error" do
setup_validator.validate_saledate(record)
expect(record.errors[:saledate]).to include("Enter a date within the 22/23 financial year, which is between 1st April 2022 and 31st March 2023")
end
end
context "when saledate is after the 22/23 financial year" do
let(:record) { build(:sales_log, saledate: Time.zone.local(2025, 4, 1)) }
it "adds error" do it "adds error" do
setup_validator.validate_saledate(record) setup_validator.validate_saledate(record)
expect(record.errors[:saledate]).to include(I18n.t("validations.setup.saledate.financial_year")) expect(record.errors[:saledate]).to include("Enter a date within the 22/23 financial year, which is between 1st April 2022 and 31st March 2023")
end
end end
end end
end end

Loading…
Cancel
Save