Browse Source

Merge branch 'main' into CLDC-1464-completion-date-validations

# Conflicts:
#	db/schema.rb
#	spec/models/form_handler_spec.rb
pull/1259/head
natdeanlewissoftwire 3 years ago
parent
commit
5e0d32fb7f
  1. 3
      app/models/form/question.rb
  2. 8
      app/models/form/sales/pages/age1.rb
  3. 13
      app/models/form/sales/pages/age2.rb
  4. 8
      app/models/form/sales/pages/buyer1_ethnic_group.rb
  5. 8
      app/models/form/sales/pages/buyer1_live_in_property.rb
  6. 8
      app/models/form/sales/pages/buyer1_working_situation.rb
  7. 13
      app/models/form/sales/pages/buyer2_live_in_property.rb
  8. 13
      app/models/form/sales/pages/buyer2_relationship_to_buyer1.rb
  9. 13
      app/models/form/sales/pages/buyer2_working_situation.rb
  10. 8
      app/models/form/sales/pages/gender_identity1.rb
  11. 13
      app/models/form/sales/pages/gender_identity2.rb
  12. 21
      app/models/form/sales/pages/monthly_charges_value_check.rb
  13. 8
      app/models/form/sales/pages/nationality1.rb
  14. 8
      app/models/form/sales/pages/number_of_others_in_property.rb
  15. 2
      app/models/form/sales/questions/discounted_ownership_type.rb
  16. 23
      app/models/form/sales/questions/monthly_charges_value_check.rb
  17. 1
      app/models/form/sales/questions/privacy_notice.rb
  18. 1
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  19. 1
      app/models/form/sales/subsections/outright_sale.rb
  20. 1
      app/models/form/sales/subsections/property_information.rb
  21. 1
      app/models/form/sales/subsections/setup.rb
  22. 1
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  23. 2
      app/models/sales_log.rb
  24. 7
      app/models/validations/sales/soft_validations.rb
  25. 25
      app/services/bulk_upload/lettings/validator.rb
  26. 5
      config/locales/en.yml
  27. 7
      db/migrate/20230127102334_add_monthly_charges_value_check.rb
  28. 7
      db/schema.rb
  29. 2
      spec/models/form/sales/pages/age1_spec.rb
  30. 13
      spec/models/form/sales/pages/age2_spec.rb
  31. 2
      spec/models/form/sales/pages/buyer1_ethnic_group_spec.rb
  32. 2
      spec/models/form/sales/pages/buyer1_live_in_property_spec.rb
  33. 11
      spec/models/form/sales/pages/buyer2_live_in_property_spec.rb
  34. 11
      spec/models/form/sales/pages/buyer2_relationship_to_buyer1_spec.rb
  35. 11
      spec/models/form/sales/pages/buyer2_working_situation_spec.rb
  36. 2
      spec/models/form/sales/pages/gender_identity1_spec.rb
  37. 13
      spec/models/form/sales/pages/gender_identity2_spec.rb
  38. 48
      spec/models/form/sales/pages/monthly_charges_value_check_spec.rb
  39. 2
      spec/models/form/sales/pages/nationality1_spec.rb
  40. 2
      spec/models/form/sales/questions/discounted_ownership_type_spec.rb
  41. 57
      spec/models/form/sales/questions/monthly_charges_value_check_spec.rb
  42. 4
      spec/models/form/sales/questions/privacy_notice_spec.rb
  43. 1
      spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb
  44. 1
      spec/models/form/sales/subsections/outright_sale_spec.rb
  45. 1
      spec/models/form/sales/subsections/property_information_spec.rb
  46. 1
      spec/models/form/sales/subsections/setup_spec.rb
  47. 1
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  48. 4
      spec/models/form_handler_spec.rb
  49. 2
      spec/models/sales_log_spec.rb
  50. 62
      spec/models/validations/sales/soft_validations_spec.rb
  51. 146
      spec/services/bulk_upload/lettings/validator_spec.rb
  52. 7
      spec/support/bulk_upload/log_to_csv.rb

3
app/models/form/question.rb

@ -14,11 +14,11 @@ class Form::Question
def initialize(id, hsh, page)
@id = id
@page = page
@guidance_position = GuidancePosition::TOP
if hsh
@check_answer_label = hsh["check_answer_label"]
@header = hsh["header"]
@guidance_partial = hsh["guidance_partial"]
@guidance_position = GuidancePosition::TOP
@hint_text = hsh["hint_text"]
@type = hsh["type"]
@min = hsh["min"]
@ -206,6 +206,7 @@ class Form::Question
def unanswered_error_message
return I18n.t("validations.declaration.missing") if id == "declaration"
return I18n.t("validations.privacynotice.missing") if id == "privacynotice"
I18n.t("validations.not_answered", question: display_label.downcase)
end

8
app/models/form/sales/pages/age1.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::Age1 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_age"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

13
app/models/form/sales/pages/age2.rb

@ -2,9 +2,16 @@ class Form::Sales::Pages::Age2 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_age"
@depends_on = [{
"jointpur" => 1,
}]
@depends_on = [
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
]
end
def questions

8
app/models/form/sales/pages/buyer1_ethnic_group.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::Buyer1EthnicGroup < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_ethnic_group"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

8
app/models/form/sales/pages/buyer1_live_in_property.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::Buyer1LiveInProperty < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_live_in_property"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

8
app/models/form/sales/pages/buyer1_working_situation.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::Buyer1WorkingSituation < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_working_situation"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

13
app/models/form/sales/pages/buyer2_live_in_property.rb

@ -2,9 +2,16 @@ class Form::Sales::Pages::Buyer2LiveInProperty < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_live_in_property"
@depends_on = [{
"jointpur" => 1,
}]
@depends_on = [
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
]
end
def questions

13
app/models/form/sales/pages/buyer2_relationship_to_buyer1.rb

@ -2,9 +2,16 @@ class Form::Sales::Pages::Buyer2RelationshipToBuyer1 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_relationship_to_buyer_1"
@depends_on = [{
"jointpur" => 1,
}]
@depends_on = [
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
]
end
def questions

13
app/models/form/sales/pages/buyer2_working_situation.rb

@ -2,9 +2,16 @@ class Form::Sales::Pages::Buyer2WorkingSituation < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_working_situation"
@depends_on = [{
"jointpur" => 1,
}]
@depends_on = [
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
]
end
def questions

8
app/models/form/sales/pages/gender_identity1.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::GenderIdentity1 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_gender_identity"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

13
app/models/form/sales/pages/gender_identity2.rb

@ -2,9 +2,16 @@ class Form::Sales::Pages::GenderIdentity2 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_gender_identity"
@depends_on = [{
"jointpur" => 1,
}]
@depends_on = [
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
]
end
def questions

21
app/models/form/sales/pages/monthly_charges_value_check.rb

@ -0,0 +1,21 @@
class Form::Sales::Pages::MonthlyChargesValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@depends_on = [
{
"monthly_charges_over_soft_max?" => true,
},
]
@title_text = {
"translation" => "soft_validations.monthly_charges_over_soft_max.title_text",
"arguments" => [],
}
@informative_text = {}
end
def questions
@questions ||= [
Form::Sales::Questions::MonthlyChargesValueCheck.new(nil, nil, self),
]
end
end

8
app/models/form/sales/pages/nationality1.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::Nationality1 < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_nationality"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

8
app/models/form/sales/pages/number_of_others_in_property.rb

@ -2,6 +2,14 @@ class Form::Sales::Pages::NumberOfOthersInProperty < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "number_of_others_in_property"
@depends_on = [
{
"privacynotice" => 1,
},
{
"noint" => 1,
},
]
end
def questions

2
app/models/form/sales/questions/discounted_ownership_type.rb

@ -9,7 +9,7 @@ class Form::Sales::Questions::DiscountedOwnershipType < ::Form::Question
end
ANSWER_OPTIONS = {
"8" => { "value" => "Right to Aquire (RTA)" },
"8" => { "value" => "Right to Acquire (RTA)" },
"14" => { "value" => "Preserved Right to Buy (PRTB)" },
"27" => { "value" => "Voluntary Right to Buy (VRTB)" },
"9" => { "value" => "Right to Buy (RTB)" },

23
app/models/form/sales/questions/monthly_charges_value_check.rb

@ -0,0 +1,23 @@
class Form::Sales::Questions::MonthlyChargesValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "monthly_charges_value_check"
@check_answer_label = "Monthly charges confirmation"
@header = "Are you sure this is correct?"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"monthly_charges_value_check" => 0,
},
{
"monthly_charges_value_check" => 1,
},
],
}
end
end

1
app/models/form/sales/questions/privacy_notice.rb

@ -6,7 +6,6 @@ class Form::Sales::Questions::PrivacyNotice < ::Form::Question
@header = "Declaration"
@type = "checkbox"
@answer_options = ANSWER_OPTIONS
@guidance_position = GuidancePosition::TOP
@guidance_partial = "privacy_notice_buyer"
end

1
app/models/form/sales/subsections/discounted_ownership_scheme.rb

@ -29,6 +29,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_deposit", nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_discounted_ownership", nil, self),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_discounted_ownership_value_check", nil, self),
]
end

1
app/models/form/sales/subsections/outright_sale.rb

@ -18,6 +18,7 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_outright_sale", nil, self),
Form::Sales::Pages::DepositValueCheck.new("outright_sale_deposit_value_check", nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_outright_sale", nil, self),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_outright_sale_value_check", nil, self),
]
end

1
app/models/form/sales/subsections/property_information.rb

@ -10,6 +10,7 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection
@pages ||= [
Form::Sales::Pages::PropertyNumberOfBedrooms.new(nil, nil, self),
Form::Sales::Pages::PropertyUnitType.new(nil, nil, self),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_property_type_value_check", nil, self),
Form::Sales::Pages::PropertyBuildingType.new(nil, nil, self),
Form::Sales::Pages::Postcode.new(nil, nil, self),
Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self),

1
app/models/form/sales/subsections/setup.rb

@ -17,6 +17,7 @@ class Form::Sales::Subsections::Setup < ::Form::Subsection
Form::Sales::Pages::DiscountedOwnershipType.new(nil, nil, self),
Form::Sales::Pages::OutrightOwnershipType.new(nil, nil, self),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("ownership_type_old_persons_shared_ownership_value_check", nil, self),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_type_value_check", nil, self),
Form::Sales::Pages::BuyerCompany.new(nil, nil, self),
Form::Sales::Pages::BuyerLive.new(nil, nil, self),
Form::Sales::Pages::JointPurchase.new(nil, nil, self),

1
app/models/form/sales/subsections/shared_ownership_scheme.rb

@ -36,6 +36,7 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::SharedOwnershipDepositValueCheck.new("shared_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::MonthlyRent.new(nil, nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_shared_ownership", nil, self),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self),
]
end

2
app/models/sales_log.rb

@ -35,7 +35,7 @@ class SalesLog < Log
scope :search_by, ->(param) { filter_by_id(param) }
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org) }
OPTIONAL_FIELDS = %w[purchid old_persons_shared_ownership_value_check].freeze
OPTIONAL_FIELDS = %w[purchid monthly_charges_value_check old_persons_shared_ownership_value_check].freeze
RETIREMENT_AGES = { "M" => 65, "F" => 60, "X" => 65 }.freeze
def startdate

7
app/models/validations/sales/soft_validations.rb

@ -75,4 +75,11 @@ module Validations::Sales::SoftValidations
!grant.between?(9_000, 16_000)
end
def monthly_charges_over_soft_max?
return unless type && mscharge && proptype
soft_max = old_persons_shared_ownership? ? 550 : 300
mscharge > soft_max
end
end

25
app/services/bulk_upload/lettings/validator.rb

@ -1,6 +1,9 @@
require "csv"
class BulkUpload::Lettings::Validator
COLUMN_PERCENTAGE_ERROR_THRESHOLD = 0.6
COLUMN_ABSOLUTE_ERROR_THRESHOLD = 16
include ActiveModel::Validations
QUESTIONS = {
@ -171,7 +174,10 @@ class BulkUpload::Lettings::Validator
end
def create_logs?
row_parsers.all?(&:valid?)
return false if any_setup_sections_incomplete?
return false if over_column_error_threshold?
row_parsers.all? { |row_parser| row_parser.log.valid? }
end
def self.question_for_field(field)
@ -180,6 +186,23 @@ class BulkUpload::Lettings::Validator
private
def any_setup_sections_incomplete?
row_parsers.any? { |row_parser| row_parser.log.form.setup_sections[0].subsections[0].is_incomplete?(row_parser.log) }
end
def over_column_error_threshold?
fields = ("field_1".."field_134").to_a
percentage_threshold = (row_parsers.size * COLUMN_PERCENTAGE_ERROR_THRESHOLD).ceil
fields.any? do |field|
count = row_parsers.count { |row_parser| row_parser.errors[field].present? }
next if count < COLUMN_ABSOLUTE_ERROR_THRESHOLD
count > percentage_threshold
end
end
def csv_parser
@csv_parser ||= BulkUpload::Lettings::CsvParser.new(path:)
end

5
config/locales/en.yml

@ -389,6 +389,9 @@ en:
declaration:
missing: "You must show the DLUHC privacy notice to the tenant before you can submit this log."
privacynotice:
missing: "You must show the DLUHC privacy notice to the buyer before you can submit this log."
scheme:
toggle_date:
@ -471,6 +474,8 @@ en:
shared_owhership_deposit:
title_text: "Mortgage, deposit and cash discount total should equal £%{expected_shared_ownership_deposit_value}"
old_persons_shared_ownership: "At least one buyer should be aged over 64 for Older persons’ shared ownership scheme"
monthly_charges_over_soft_max:
title_text: "The amount of monthly charges is high for this type of property and sale type"
devise:
two_factor_authentication:

7
db/migrate/20230127102334_add_monthly_charges_value_check.rb

@ -0,0 +1,7 @@
class AddMonthlyChargesValueCheck < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :monthly_charges_value_check, :integer
end
end
end

7
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_01_26_145529) do
ActiveRecord::Schema[7.0].define(version: 2023_01_27_102334) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -504,11 +504,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_26_145529) do
t.integer "retirement_value_check"
t.integer "hodate_check"
t.integer "extrabor_value_check"
t.integer "grant_value_check"
t.integer "staircase_bought_value_check"
t.integer "deposit_and_mortgage_value_check"
t.integer "shared_ownership_deposit_value_check"
t.integer "grant_value_check"
t.integer "old_persons_shared_ownership_value_check"
t.integer "staircase_bought_value_check"
t.integer "monthly_charges_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 ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id"

2
spec/models/form/sales/pages/age1_spec.rb

@ -28,6 +28,6 @@ RSpec.describe Form::Sales::Pages::Age1, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }])
end
end

13
spec/models/form/sales/pages/age2_spec.rb

@ -28,8 +28,15 @@ RSpec.describe Form::Sales::Pages::Age2, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"jointpur" => 1,
}])
expect(page.depends_on).to eq([
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
])
end
end

2
spec/models/form/sales/pages/buyer1_ethnic_group_spec.rb

@ -28,6 +28,6 @@ RSpec.describe Form::Sales::Pages::Buyer1EthnicGroup, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }])
end
end

2
spec/models/form/sales/pages/buyer1_live_in_property_spec.rb

@ -28,6 +28,6 @@ RSpec.describe Form::Sales::Pages::Buyer1LiveInProperty, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }])
end
end

11
spec/models/form/sales/pages/buyer2_live_in_property_spec.rb

@ -28,6 +28,15 @@ RSpec.describe Form::Sales::Pages::Buyer2LiveInProperty, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "jointpur" => 1 }])
expect(page.depends_on).to eq([
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
])
end
end

11
spec/models/form/sales/pages/buyer2_relationship_to_buyer1_spec.rb

@ -28,6 +28,15 @@ RSpec.describe Form::Sales::Pages::Buyer2RelationshipToBuyer1, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "jointpur" => 1 }])
expect(page.depends_on).to eq([
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
])
end
end

11
spec/models/form/sales/pages/buyer2_working_situation_spec.rb

@ -28,6 +28,15 @@ RSpec.describe Form::Sales::Pages::Buyer2WorkingSituation, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "jointpur" => 1 }])
expect(page.depends_on).to eq([
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
])
end
end

2
spec/models/form/sales/pages/gender_identity1_spec.rb

@ -28,6 +28,6 @@ RSpec.describe Form::Sales::Pages::GenderIdentity1, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }])
end
end

13
spec/models/form/sales/pages/gender_identity2_spec.rb

@ -28,8 +28,15 @@ RSpec.describe Form::Sales::Pages::GenderIdentity2, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"jointpur" => 1,
}])
expect(page.depends_on).to eq([
{
"jointpur" => 1,
"privacynotice" => 1,
},
{
"jointpur" => 1,
"noint" => 1,
},
])
end
end

48
spec/models/form/sales/pages/monthly_charges_value_check_spec.rb

@ -0,0 +1,48 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::MonthlyChargesValueCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "monthly_charges_value_check" }
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[monthly_charges_value_check])
end
it "has the correct id" do
expect(page.id).to eq("monthly_charges_value_check")
end
it "has the correct header" do
expect(page.header).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"monthly_charges_over_soft_max?" => true,
},
])
end
it "is interruption screen page" do
expect(page.interruption_screen?).to eq(true)
end
it "has correct title_text" do
expect(page.title_text).to eq({
"translation" => "soft_validations.monthly_charges_over_soft_max.title_text",
"arguments" => [],
})
end
it "has correct informative_text" do
expect(page.informative_text).to eq({})
end
end

2
spec/models/form/sales/pages/nationality1_spec.rb

@ -28,6 +28,6 @@ RSpec.describe Form::Sales::Pages::Nationality1, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([{ "privacynotice" => 1 }, { "noint" => 1 }])
end
end

2
spec/models/form/sales/questions/discounted_ownership_type_spec.rb

@ -33,7 +33,7 @@ RSpec.describe Form::Sales::Questions::DiscountedOwnershipType, type: :model do
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"8" => { "value" => "Right to Aquire (RTA)" },
"8" => { "value" => "Right to Acquire (RTA)" },
"14" => { "value" => "Preserved Right to Buy (PRTB)" },
"27" => { "value" => "Voluntary Right to Buy (VRTB)" },
"9" => { "value" => "Right to Buy (RTB)" },

57
spec/models/form/sales/questions/monthly_charges_value_check_spec.rb

@ -0,0 +1,57 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::MonthlyChargesValueCheck, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { "monthly_charges_value_check" }
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("monthly_charges_value_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure this is correct?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Monthly 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" => [
{
"monthly_charges_value_check" => 0,
},
{
"monthly_charges_value_check" => 1,
},
],
})
end
end

4
spec/models/form/sales/questions/privacy_notice_spec.rb

@ -40,4 +40,8 @@ RSpec.describe Form::Sales::Questions::PrivacyNotice, type: :model do
"privacynotice" => { "value" => "The buyer has seen the DLUHC privacy notice" },
})
end
it "returns correct unanswered_error_message" do
expect(question.unanswered_error_message).to eq("You must show the DLUHC privacy notice to the buyer before you can submit this log.")
end
end

1
spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb

@ -35,6 +35,7 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model
discounted_ownership_deposit_value_check
discounted_ownership_deposit_and_mortgage_value_check_after_deposit
leasehold_charges_discounted_ownership
monthly_charges_discounted_ownership_value_check
],
)
end

1
spec/models/form/sales/subsections/outright_sale_spec.rb

@ -24,6 +24,7 @@ RSpec.describe Form::Sales::Subsections::OutrightSale, type: :model do
about_deposit_outright_sale
outright_sale_deposit_value_check
leasehold_charges_outright_sale
monthly_charges_outright_sale_value_check
],
)
end

1
spec/models/form/sales/subsections/property_information_spec.rb

@ -16,6 +16,7 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do
%w[
property_number_of_bedrooms
property_unit_type
monthly_charges_property_type_value_check
property_building_type
property_postcode
property_local_authority

1
spec/models/form/sales/subsections/setup_spec.rb

@ -24,6 +24,7 @@ RSpec.describe Form::Sales::Subsections::Setup, type: :model do
discounted_ownership_type
outright_ownership_type
ownership_type_old_persons_shared_ownership_value_check
monthly_charges_type_value_check
buyer_company
buyer_live
joint_purchase

1
spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb

@ -42,6 +42,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
shared_ownership_deposit_value_check
monthly_rent
leasehold_charges_shared_ownership
monthly_charges_shared_ownership_value_check
],
)
end

4
spec/models/form_handler_spec.rb

@ -52,14 +52,14 @@ RSpec.describe FormHandler do
it "is able to load a current sales form" do
form = form_handler.get_form("current_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(199)
expect(form.pages.count).to eq(204)
expect(form.name).to eq("2022_2023_sales")
end
it "is able to load a previous sales form" do
form = form_handler.get_form("previous_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(199)
expect(form.pages.count).to eq(204)
expect(form.name).to eq("2021_2022_sales")
end
end

2
spec/models/sales_log_spec.rb

@ -47,7 +47,7 @@ RSpec.describe SalesLog, type: :model do
let(:sales_log) { build(:sales_log) }
it "returns optional fields" do
expect(sales_log.optional_fields).to eq(%w[purchid old_persons_shared_ownership_value_check])
expect(sales_log.optional_fields).to eq(%w[purchid monthly_charges_value_check old_persons_shared_ownership_value_check])
end
end

62
spec/models/validations/sales/soft_validations_spec.rb

@ -593,4 +593,66 @@ RSpec.describe Validations::Sales::SoftValidations do
expect(record).to be_staircase_bought_above_fifty
end
end
describe "#monthly_charges_over_soft_max?" do
it "returns false if mscharge is not given" do
record.mscharge = nil
record.proptype = 4
record.type = 2
expect(record).not_to be_monthly_charges_over_soft_max
end
it "returns false if proptype is not given" do
record.mscharge = 999
record.proptype = nil
record.type = 2
expect(record).not_to be_monthly_charges_over_soft_max
end
it "returns false if type is not given" do
record.mscharge = 999
record.proptype = 4
record.type = nil
expect(record).not_to be_monthly_charges_over_soft_max
end
context "with old persons shared ownership" do
it "returns false if the monthly charge is under 550" do
record.mscharge = 540
record.proptype = 4
record.type = 24
expect(record).not_to be_monthly_charges_over_soft_max
end
it "returns true if the monthly charge is over 550" do
record.mscharge = 999
record.proptype = 4
record.type = 24
expect(record).to be_monthly_charges_over_soft_max
end
end
context "with non old persons type of ownership" do
it "returns false if the monthly charge is under 300" do
record.mscharge = 280
record.proptype = 4
record.type = 18
expect(record).not_to be_monthly_charges_over_soft_max
end
it "returns true if the monthly charge is over 300" do
record.mscharge = 400
record.proptype = 4
record.type = 18
expect(record).to be_monthly_charges_over_soft_max
end
end
end
end

146
spec/services/bulk_upload/lettings/validator_spec.rb

@ -78,7 +78,7 @@ RSpec.describe BulkUpload::Lettings::Validator do
before do
file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.rewind
file.close
end
it "creates validation errors" do
@ -112,4 +112,148 @@ RSpec.describe BulkUpload::Lettings::Validator do
end
end
end
describe "#create_logs?" do
context "when a log is not valid?" do
let(:log_1) { build(:lettings_log, :completed, created_by: user) }
let(:log_2) { build(:lettings_log, :completed, created_by: user) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides: { illness: 100 }).to_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
end
end
context "when all logs valid?" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_2) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns true" do
validator.call
expect(validator).to be_create_logs
end
end
context "when a log has incomplete setup secion" do
let(:log) { build(:lettings_log, :in_progress, created_by: user, startdate: Time.zone.local(2022, 5, 1)) }
before do
file.write(BulkUpload::LogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
end
end
context "when a column has error rate below absolute threshold" do
context "when a column is over 60% error threshold" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_2) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_3) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_4) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns true" do
validator.call
expect(validator).to be_create_logs
end
end
context "when a column is under 60% error threshold" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_2) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_3) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_4) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns true" do
validator.call
expect(validator).to be_create_logs
end
end
end
context "when a column has error rate above absolute threshold" do
before do
stub_const("BulkUpload::Lettings::Validator::COLUMN_ABSOLUTE_ERROR_THRESHOLD", 1)
end
context "when a column is over 60% error threshold" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_2) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_3) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_4) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
end
end
context "when a column is under 60% error threshold" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_2) { build(:lettings_log, :completed, renttype: 1, created_by: user) }
let(:log_3) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_4) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
let(:log_5) { build(:lettings_log, renttype: 2, created_by: user, builtype: nil, startdate: Time.zone.local(2022, 5, 1)) }
before do
file.write(BulkUpload::LogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_3, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_4, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.write(BulkUpload::LogToCsv.new(log: log_5, line_ending: "\r\n", col_offset: 0).to_csv_row)
file.close
end
it "returns true" do
validator.call
expect(validator).to be_create_logs
end
end
end
end
end

7
spec/support/bulk_upload/log_to_csv.rb

@ -1,10 +1,11 @@
class BulkUpload::LogToCsv
attr_reader :log, :line_ending, :col_offset
attr_reader :log, :line_ending, :col_offset, :overrides
def initialize(log:, line_ending: "\n", col_offset: 1)
def initialize(log:, line_ending: "\n", col_offset: 1, overrides: {})
@log = log
@line_ending = line_ending
@col_offset = col_offset
@overrides = overrides
end
def to_csv_row
@ -135,7 +136,7 @@ class BulkUpload::LogToCsv
nil,
log.incfreq,
log.sheltered,
log.illness,
overrides[:illness] || log.illness,
log.illness_type_1,
log.illness_type_2, # 120

Loading…
Cancel
Save