Browse Source

Merge remote-tracking branch 'origin/CLDC-3758-Add-shared-ownership-staircasing-transaction' into CLDC-3758-Add-shared-ownership-staircasing-transaction

pull/2788/head
Manny Dinssa 7 months ago
parent
commit
04a5de0d3e
  1. 14
      app/controllers/schemes_controller.rb
  2. 3
      app/frontend/styles/_table-group.scss
  3. 2
      app/helpers/form_page_error_helper.rb
  4. 10
      app/helpers/schemes_helper.rb
  5. 2
      app/models/derived_variables/sales_log_variables.rb
  6. 14
      app/models/form/sales/pages/buyer2_relationship_to_buyer1_yes_no.rb
  7. 15
      app/models/form/sales/pages/person_relationship_to_buyer_1_yes_no.rb
  8. 1
      app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb
  9. 23
      app/models/form/sales/questions/buyer2_relationship_to_buyer1_yes_no.rb
  10. 29
      app/models/form/sales/questions/person_relationship_to_buyer_1_yes_no.rb
  11. 1
      app/models/form/sales/questions/staircase_count.rb
  12. 14
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  13. 23
      app/models/form/sales/subsections/household_characteristics.rb
  14. 5
      app/models/validations/sales/financial_validations.rb
  15. 17
      app/models/validations/sales/sale_information_validations.rb
  16. 6
      app/views/schemes/confirm_secondary.html.erb
  17. 2
      app/views/schemes/details.html.erb
  18. 2
      app/views/schemes/edit_name.html.erb
  19. 8
      app/views/schemes/primary_client_group.html.erb
  20. 6
      app/views/schemes/secondary_client_group.html.erb
  21. 6
      app/views/schemes/support.html.erb
  22. 24
      config/locales/forms/2025/sales/household_characteristics.en.yml
  23. 4
      config/locales/validations/sales/financial.en.yml
  24. 6
      config/locales/validations/sales/sale_information.en.yml
  25. 27
      spec/features/schemes_spec.rb
  26. 29
      spec/models/form/sales/pages/buyer2_relationship_to_buyer1_yes_no_spec.rb
  27. 87
      spec/models/form/sales/pages/person_relationship_to_buyer1_yes_no_spec.rb
  28. 43
      spec/models/form/sales/questions/buyer2_relationship_to_buyer1_yes_no_spec.rb
  29. 110
      spec/models/form/sales/questions/person_relationship_to_buyer1_yes_no_spec.rb
  30. 44
      spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb
  31. 185
      spec/models/form/sales/subsections/household_characteristics_spec.rb
  32. 10
      spec/models/validations/sales/financial_validations_spec.rb
  33. 40
      spec/models/validations/sales/sale_information_validations_spec.rb
  34. 42
      spec/requests/schemes_controller_spec.rb
  35. 6
      yarn.lock

14
app/controllers/schemes_controller.rb

@ -145,8 +145,8 @@ class SchemesController < ApplicationController
if @scheme.errors.empty? && @scheme.update(scheme_params)
@scheme.update!(secondary_client_group: nil) if @scheme.has_other_client_group == "No"
if scheme_params[:confirmed] == "true" || @scheme.confirmed?
if check_answers && confirm_secondary_page?(page)
redirect_to scheme_secondary_client_group_path(@scheme, check_answers: "true")
if check_answers && should_direct_via_secondary_client_group_page?(page)
redirect_to scheme_secondary_client_group_path(@scheme, referrer: "check-answers")
else
@scheme.locations.update!(confirmed: true)
flash[:notice] = if scheme_previously_confirmed
@ -157,8 +157,8 @@ class SchemesController < ApplicationController
redirect_to scheme_path(@scheme)
end
elsif check_answers
if confirm_secondary_page?(page)
redirect_to scheme_secondary_client_group_path(@scheme, check_answers: "true")
if should_direct_via_secondary_client_group_page?(page)
redirect_to scheme_secondary_client_group_path(@scheme, referrer: "check-answers")
else
redirect_to scheme_check_answers_path(@scheme)
end
@ -249,8 +249,8 @@ private
end
end
def confirm_secondary_page?(page)
page == "confirm-secondary" && @scheme.has_other_client_group == "Yes"
def should_direct_via_secondary_client_group_page?(page)
page == "confirm-secondary" && @scheme.has_other_client_group == "Yes" && @scheme.secondary_client_group.nil?
end
def current_template(page)
@ -293,9 +293,9 @@ private
def scheme_params
required_params = params.require(:scheme).permit(:service_name,
:sensitive,
:owning_organisation_id,
:scheme_type,
:registered_under_care_act,
:owning_organisation_id,
:id,
:has_other_client_group,
:primary_client_group,

3
app/frontend/styles/_table-group.scss

@ -24,7 +24,8 @@
}
.scheme-name-cell {
word-break: break-all;
overflow-wrap: break-word;
word-break: break-word;
}
.app-table-group:focus {

2
app/helpers/form_page_error_helper.rb

@ -14,6 +14,6 @@ module FormPageErrorHelper
end
def all_questions_affected_by_errors(log)
log.errors.map(&:attribute) - [:base]
(log.errors.map(&:attribute) - [:base]).uniq
end
end

10
app/helpers/schemes_helper.rb

@ -64,15 +64,15 @@ module SchemesHelper
def change_answer_link(scheme, question_id, user)
case question_id
when "service_name", "sensitive", "scheme_type", "registered_under_care_act", "owning_organisation_id", "arrangement_type"
user.support? || !scheme.confirmed? ? scheme_details_path(scheme, check_answers: true) : scheme_edit_name_path(scheme)
user.support? || !scheme.confirmed? ? scheme_details_path(scheme, referrer: "check-answers") : scheme_edit_name_path(scheme)
when "primary_client_group"
scheme_primary_client_group_path(scheme, check_answers: true)
scheme_primary_client_group_path(scheme, referrer: "check-answers")
when "has_other_client_group"
scheme_confirm_secondary_client_group_path(scheme, check_answers: true)
scheme_confirm_secondary_client_group_path(scheme, referrer: "check-answers")
when "secondary_client_group"
scheme_secondary_client_group_path(scheme, check_answers: true)
scheme_secondary_client_group_path(scheme, referrer: "check-answers")
when "support_type", "intended_stay"
scheme_support_path(scheme, check_answers: true)
scheme_support_path(scheme, referrer: "check-answers")
end
end

2
app/models/derived_variables/sales_log_variables.rb

@ -75,7 +75,7 @@ module DerivedVariables::SalesLogVariables
self.nationality_all = nationality_all_group if nationality_uk_or_prefers_not_to_say?
self.nationality_all_buyer2 = nationality_all_buyer2_group if nationality2_uk_or_prefers_not_to_say?
self.numstair = 1 if is_firststair?
self.numstair = is_firststair? ? 1 : nil if numstair == 1 && firststair_changed?
self.mrent = 0 if stairowned_100?
set_encoded_derived_values!(DEPENDENCIES)

14
app/models/form/sales/pages/buyer2_relationship_to_buyer1_yes_no.rb

@ -0,0 +1,14 @@
class Form::Sales::Pages::Buyer2RelationshipToBuyer1YesNo < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_2_relationship_to_buyer_1"
@copy_key = "sales.household_characteristics.relat2.buyer"
@depends_on = [{ "joint_purchase?" => true }]
end
def questions
@questions ||= [
Form::Sales::Questions::Buyer2RelationshipToBuyer1YesNo.new(nil, nil, self),
]
end
end

15
app/models/form/sales/pages/person_relationship_to_buyer_1_yes_no.rb

@ -0,0 +1,15 @@
class Form::Sales::Pages::PersonRelationshipToBuyer1YesNo < ::Form::Sales::Pages::Person
def initialize(id, hsh, subsection, person_index:)
super
@copy_key = "sales.household_characteristics.relat2.person" if person_index == 2
@depends_on = [
{ "details_known_#{person_index}" => 1 },
]
end
def questions
@questions ||= [
Form::Sales::Questions::PersonRelationshipToBuyer1YesNo.new("relat#{@person_index}", nil, self, person_index: @person_index),
]
end
end

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

@ -17,7 +17,6 @@ class Form::Sales::Questions::Buyer2RelationshipToBuyer1 < ::Form::Question
def answer_options
if form.start_year_2024_or_later?
{
"P" => { "value" => "Partner" },
"C" => { "value" => "Child" },

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

@ -0,0 +1,23 @@
class Form::Sales::Questions::Buyer2RelationshipToBuyer1YesNo < ::Form::Question
def initialize(id, hsh, page)
super
@id = "relat2"
@copy_key = "sales.household_characteristics.relat2.buyer"
@type = "radio"
@answer_options = {
"P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Buyer prefers not to say" },
}
@inferred_check_answers_value = [{
"condition" => {
"relat2" => "R",
},
"value" => "Prefers not to say",
}]
@check_answers_card_number = 2
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 29 }.freeze
end

29
app/models/form/sales/questions/person_relationship_to_buyer_1_yes_no.rb

@ -0,0 +1,29 @@
class Form::Sales::Questions::PersonRelationshipToBuyer1YesNo < ::Form::Question
def initialize(id, hsh, page, person_index:)
super(id, hsh, page)
@type = "radio"
@copy_key = "sales.household_characteristics.relat2.person" if person_index == 2
@answer_options = {
"P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Person prefers not to say" },
}
@inferred_check_answers_value = [{
"condition" => {
id => "R",
},
"value" => "Prefers not to say",
}]
@check_answers_card_number = person_index
@person_index = person_index
@question_number = question_number
end
def question_number
base_question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
base_question_number + (4 * @person_index)
end
QUESTION_NUMBER_FROM_YEAR = { 2025 => 30 }.freeze
end

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

@ -6,6 +6,7 @@ class Form::Sales::Questions::StaircaseCount < ::Form::Question
@type = "numeric"
@width = 2
@min = 2
@max = 10
@step = 1
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end

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

@ -28,8 +28,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::DiscountedSaleValueCheck.new("discounted_sale_mortgage_value_check", nil, self),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_mortgage_value_check", nil, self),
Form::Sales::Pages::DepositAndMortgageValueCheck.new("discounted_ownership_deposit_and_mortgage_value_check_after_mortgage", nil, self),
Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_discounted_ownership", nil, self, ownershipsch: 2),
mortgage_lender_questions,
Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_value_check", nil, self),
@ -41,10 +40,19 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::DiscountedSaleValueCheck.new("discounted_sale_deposit_value_check", nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_discounted_ownership_value_check", nil, self),
]
].flatten.compact
end
def displayed_in_tasklist?(log)
log.ownershipsch.nil? || log.ownershipsch == 2
end
def mortgage_lender_questions
unless form.start_year_2025_or_later?
[
Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self, ownershipsch: 2),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_discounted_ownership", nil, self, ownershipsch: 2),
]
end
end
end

23
app/models/form/sales/subsections/household_characteristics.rb

@ -3,7 +3,14 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
super
@id = "household_characteristics"
@label = "Household characteristics"
@depends_on = [{ "setup_completed?" => true, "company_buyer?" => false }]
end
def depends_on
if form.start_year_2025_or_later?
[{ "setup_completed?" => true }]
else
[{ "setup_completed?" => true, "company_buyer?" => false }]
end
end
def pages
@ -31,7 +38,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::Buyer1IncomeMinValueCheck.new("working_situation_buyer_1_income_min_value_check", nil, self),
Form::Sales::Pages::Buyer1LiveInProperty.new(nil, nil, self),
Form::Sales::Pages::BuyerLiveInValueCheck.new("buyer_1_live_in_property_value_check", nil, self, person_index: 1),
Form::Sales::Pages::Buyer2RelationshipToBuyer1.new(nil, nil, self),
(form.start_year_2025_or_later? ? Form::Sales::Pages::Buyer2RelationshipToBuyer1YesNo.new(nil, nil, self) : Form::Sales::Pages::Buyer2RelationshipToBuyer1.new(nil, nil, self)),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_relationship_student_not_child_value_check", nil, self, person_index: 2),
Form::Sales::Pages::Age2.new(nil, nil, self),
Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("age_2_old_persons_shared_ownership_joint_purchase_value_check", nil, self, joint_purchase: true),
@ -51,7 +58,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property", nil, self, joint_purchase: false),
Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property_joint_purchase", nil, self, joint_purchase: true),
Form::Sales::Pages::PersonKnown.new("person_2_known", nil, self, person_index: 2),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_2_relationship_to_buyer_1", nil, self, person_index: 2),
(form.start_year_2025_or_later? ? Form::Sales::Pages::PersonRelationshipToBuyer1YesNo.new("person_2_relationship_to_buyer_1", nil, self, person_index: 2) : Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_2_relationship_to_buyer_1", nil, self, person_index: 2)),
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("relationship_2_partner_under_16_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
(Form::Sales::Pages::MultiplePartnersValueCheck.new("relationship_2_multiple_partners_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_2_student_not_child_value_check", nil, self, person_index: 2),
@ -66,7 +73,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::NotRetiredValueCheck.new("working_situation_2_not_retired_value_check", nil, self, person_index: 2) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_2_student_not_child_value_check", nil, self, person_index: 2),
Form::Sales::Pages::PersonKnown.new("person_3_known", nil, self, person_index: 3),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_3_relationship_to_buyer_1", nil, self, person_index: 3),
(form.start_year_2025_or_later? ? Form::Sales::Pages::PersonRelationshipToBuyer1YesNo.new("person_3_relationship_to_buyer_1", nil, self, person_index: 3) : Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_3_relationship_to_buyer_1", nil, self, person_index: 3)),
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("relationship_3_partner_under_16_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?),
(Form::Sales::Pages::MultiplePartnersValueCheck.new("relationship_3_multiple_partners_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_3_student_not_child_value_check", nil, self, person_index: 3),
@ -81,7 +88,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::NotRetiredValueCheck.new("working_situation_3_not_retired_value_check", nil, self, person_index: 3) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_3_student_not_child_value_check", nil, self, person_index: 3),
Form::Sales::Pages::PersonKnown.new("person_4_known", nil, self, person_index: 4),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_4_relationship_to_buyer_1", nil, self, person_index: 4),
(form.start_year_2025_or_later? ? Form::Sales::Pages::PersonRelationshipToBuyer1YesNo.new("person_4_relationship_to_buyer_1", nil, self, person_index: 4) : Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_4_relationship_to_buyer_1", nil, self, person_index: 4)),
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("relationship_4_partner_under_16_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?),
(Form::Sales::Pages::MultiplePartnersValueCheck.new("relationship_4_multiple_partners_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_4_student_not_child_value_check", nil, self, person_index: 4),
@ -96,7 +103,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::NotRetiredValueCheck.new("working_situation_4_not_retired_value_check", nil, self, person_index: 4) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_4_student_not_child_value_check", nil, self, person_index: 4),
Form::Sales::Pages::PersonKnown.new("person_5_known", nil, self, person_index: 5),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_5_relationship_to_buyer_1", nil, self, person_index: 5),
(form.start_year_2025_or_later? ? Form::Sales::Pages::PersonRelationshipToBuyer1YesNo.new("person_5_relationship_to_buyer_1", nil, self, person_index: 5) : Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_5_relationship_to_buyer_1", nil, self, person_index: 5)),
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("relationship_5_partner_under_16_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?),
(Form::Sales::Pages::MultiplePartnersValueCheck.new("relationship_5_multiple_partners_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_5_student_not_child_value_check", nil, self, person_index: 5),
@ -111,7 +118,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
(Form::Sales::Pages::NotRetiredValueCheck.new("working_situation_5_not_retired_value_check", nil, self, person_index: 5) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("working_situation_5_student_not_child_value_check", nil, self, person_index: 5),
Form::Sales::Pages::PersonKnown.new("person_6_known", nil, self, person_index: 6),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_6_relationship_to_buyer_1", nil, self, person_index: 6),
(form.start_year_2025_or_later? ? Form::Sales::Pages::PersonRelationshipToBuyer1YesNo.new("person_6_relationship_to_buyer_1", nil, self, person_index: 6) : Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_6_relationship_to_buyer_1", nil, self, person_index: 6)),
(Form::Sales::Pages::PartnerUnder16ValueCheck.new("relationship_6_partner_under_16_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?),
(Form::Sales::Pages::MultiplePartnersValueCheck.new("relationship_6_multiple_partners_value_check", nil, self, person_index: 6) if form.start_year_2024_or_later?),
Form::Sales::Pages::PersonStudentNotChildValueCheck.new("relationship_6_student_not_child_value_check", nil, self, person_index: 6),
@ -143,6 +150,8 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
end
def displayed_in_tasklist?(log)
return true if form.start_year_2025_or_later?
!log.company_buyer?
end
end

5
app/models/validations/sales/financial_validations.rb

@ -73,8 +73,9 @@ module Validations::Sales::FinancialValidations
end
if threshold && record.stairbought < threshold
record.errors.add :stairbought, I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold:)
record.errors.add :type, I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold:)
shared_ownership_type = record.form.get_question("type", record).label_from_value(record.type).downcase
record.errors.add :stairbought, I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold:, shared_ownership_type:)
record.errors.add :type, I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold:, shared_ownership_type:)
end
end

17
app/models/validations/sales/sale_information_validations.rb

@ -32,6 +32,14 @@ module Validations::Sales::SaleInformationValidations
end
end
def validate_staircasing_initial_purchase_date(record)
return unless record.initialpurchase
if record.initialpurchase < Time.zone.local(1980, 1, 1)
record.errors.add :initialpurchase, I18n.t("validations.sales.sale_information.initialpurchase.must_be_after_1980")
end
end
def validate_previous_property_unit_type(record)
return unless record.fromprop && record.frombeds
@ -348,6 +356,15 @@ module Validations::Sales::SaleInformationValidations
end
end
def validate_number_of_staircase_transactions(record)
return unless record.numstair
if record.firststair == 2 && record.numstair < 2
record.errors.add :numstair, I18n.t("validations.sales.sale_information.numstair.must_be_greater_than_one")
record.errors.add :firststair, I18n.t("validations.sales.sale_information.firststair.cannot_be_no")
end
end
def over_tolerance?(expected, actual, tolerance, strict: false)
if strict
(expected - actual).abs > tolerance

6
app/views/schemes/confirm_secondary.html.erb

@ -1,9 +1,7 @@
<% content_for :title, "Does this scheme provide for another client group?" %>
<% content_for :before_content do %>
<%= govuk_back_link(
href: request.query_parameters["check_answers"] ? "check-answers" : "primary-client-group",
) %>
<%= govuk_back_link(href: :back) %>
<% end %>
<%= render partial: "organisations/headings", locals: { main: "Does this scheme provide for another client group?", sub: @scheme.service_name } %>
@ -22,7 +20,7 @@
legend: nil %>
<%= f.hidden_field :page, value: "confirm-secondary" %>
<% if request.query_parameters["check_answers"] == "true" %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<%= f.govuk_submit "Save changes" %>
<% else %>

2
app/views/schemes/details.html.erb

@ -75,7 +75,7 @@
legend: { text: "Who provides the support services used by this scheme?", size: "m" } %>
<%= f.hidden_field :page, value: "details" %>
<% if request.query_parameters["check_answers"] %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<%= f.govuk_submit "Save changes" %>
<% else %>

2
app/views/schemes/edit_name.html.erb

@ -39,7 +39,7 @@
<%= f.hidden_field :page, value: "edit-name" %>
<% if request.query_parameters["check_answers"] %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<% end %>

8
app/views/schemes/primary_client_group.html.erb

@ -1,9 +1,9 @@
<% content_for :title, "What client group is this scheme intended for?" %>
<% if request.referer&.include?("new") || request.referer&.include?("details") %>
<% if request.referer&.include?("new") %>
<% back_button_path = scheme_details_path(@scheme) %>
<% elsif request.query_parameters["check_answers"] %>
<% back_button_path = scheme_check_answers_path(@scheme) %>
<% else %>
<% back_button_path = :back %>
<% end %>
<% content_for :before_content do %>
@ -30,7 +30,7 @@
<%= f.hidden_field :check_answers, value: "true" %>
<% end %>
<% if request.query_parameters["check_answers"] == "true" %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<%= f.govuk_submit "Save changes" %>
<% else %>

6
app/views/schemes/secondary_client_group.html.erb

@ -1,9 +1,7 @@
<% content_for :title, "What is the other client group?" %>
<% content_for :before_content do %>
<%= govuk_back_link(
href: request.query_parameters["check_answers"] ? "check-answers" : "confirm-secondary-client-group",
) %>
<%= govuk_back_link(href: :back) %>
<% end %>
<%= form_for(@scheme, method: :patch) do |f| %>
@ -22,7 +20,7 @@
legend: nil %>
<%= f.hidden_field :page, value: "secondary-client-group" %>
<% if request.query_parameters["check_answers"] == "true" %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<%= f.govuk_submit "Save changes" %>
<% else %>

6
app/views/schemes/support.html.erb

@ -1,9 +1,7 @@
<% content_for :title, "What support does this scheme provide?" %>
<% content_for :before_content do %>
<%= govuk_back_link(
href: request.query_parameters["check_answers"] ? "check-answers" : "secondary-client-group",
) %>
<%= govuk_back_link(href: :back) %>
<% end %>
<%= form_for(@scheme, method: :patch) do |f| %>
@ -38,7 +36,7 @@
<%= f.hidden_field :page, value: "support" %>
<% if request.query_parameters["check_answers"] == "true" %>
<% if params[:referrer] == "check-answers" %>
<%= f.hidden_field :check_answers, value: "true" %>
<%= f.govuk_submit "Save changes" %>
<% else %>

24
config/locales/forms/2025/sales/household_characteristics.en.yml

@ -80,14 +80,14 @@ en:
relat2:
buyer:
page_header: ""
check_answer_label: "Buyer 2's relationship to buyer 1"
check_answer_label: "Buyer 2 is the partner of buyer 1"
hint_text: ""
question_text: "What is buyer 2's relationship to buyer 1?"
question_text: "Is buyer 2 the partner of buyer 1?"
person:
page_header: ""
check_answer_label: "Person 2’s relationship to Buyer 1"
check_answer_label: "Person 2 is the partner of buyer 1"
hint_text: ""
question_text: "What is Person 2’s relationship to Buyer 1?"
question_text: "Is person 2 the partner of buyer 1?"
age2:
buyer:
@ -212,9 +212,9 @@ en:
relat3:
page_header: ""
check_answer_label: "Person 3’s relationship to Buyer 1"
check_answer_label: "Person 3 is the partner of buyer 1"
hint_text: ""
question_text: "What is Person 3’s relationship to Buyer 1?"
question_text: "Is person 3 the partner of buyer 1?"
age3:
page_header: ""
@ -247,9 +247,9 @@ en:
relat4:
page_header: ""
check_answer_label: "Person 4’s relationship to Buyer 1"
check_answer_label: "Person 4 is the partner of buyer 1"
hint_text: ""
question_text: "What is Person 4’s relationship to Buyer 1?"
question_text: "Is person 4 the partner of buyer 1?"
age4:
page_header: ""
@ -282,9 +282,9 @@ en:
relat5:
page_header: ""
check_answer_label: "Person 5’s relationship to Buyer 1"
check_answer_label: "Person 5 is the partner of buyer 1"
hint_text: ""
question_text: "What is Person 5’s relationship to Buyer 1?"
question_text: "Is person 5 the partner of buyer 1?"
age5:
page_header: ""
@ -317,9 +317,9 @@ en:
relat6:
page_header: ""
check_answer_label: "Person 6’s relationship to Buyer 1"
check_answer_label: "Person 6 is the partner of buyer 1"
hint_text: ""
question_text: "What is Person 6’s relationship to Buyer 1?"
question_text: "Is person 6 the partner of buyer 1?"
age6:
page_header: ""

4
config/locales/validations/sales/financial.en.yml

@ -55,7 +55,7 @@ en:
type:
equity_under_min: "The minimum initial equity stake for this type of shared ownership sale is %{min_equity}%."
equity_over_max: "The maximum initial equity stake is %{max_equity}%."
percentage_bought_must_be_at_least_threshold: "The minimum increase in equity while staircasing is %{threshold}% for this shared ownership type."
percentage_bought_must_be_at_least_threshold: "The minimum percentage share that can be bought in a staircasing transaction for %{shared_ownership_type} is %{threshold}%. Please change your answer or check that you have selected the correct shared ownership type."
equity:
equity_under_min: "The minimum initial equity stake for this type of shared ownership sale is %{min_equity}%."
@ -77,7 +77,7 @@ en:
equity_over_stairowned_minus_stairbought:
joint_purchase: "The initial equity stake is %{equity}% and the percentage owned in total minus the percentage bought is %{staircase_difference}%. In a staircasing transaction, the equity stake purchased cannot be larger than the percentage the buyers own minus the percentage bought."
not_joint_purchase: "The initial equity stake is %{equity}% and the percentage owned in total minus the percentage bought is %{staircase_difference}%. In a staircasing transaction, the equity stake purchased cannot be larger than the percentage the buyer owns minus the percentage bought."
percentage_bought_must_be_at_least_threshold: "The minimum increase in equity while staircasing is %{threshold}%."
percentage_bought_must_be_at_least_threshold: "The minimum percentage share that can be bought in a staircasing transaction for %{shared_ownership_type} is %{threshold}%. Please change your answer or check that you have selected the correct shared ownership type."
percentage_bought_equal_percentage_owned: "The percentage bought is %{stairbought}% and the percentage owned in total is %{stairowned}%. These figures cannot be the same."
uprn_selection:

6
config/locales/validations/sales/sale_information.en.yml

@ -17,6 +17,8 @@ en:
exdate:
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."
initialpurchase:
must_be_after_1980: "The initial purchase date must be after January 1, 1980."
fromprop:
previous_property_type_bedsit: "A bedsit cannot have more than 1 bedroom."
frombeds:
@ -123,3 +125,7 @@ en:
postcode_full:
value_over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London."
value_over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London."
numstair:
must_be_greater_than_one: "The number of staircasing transactions must be greater than 1 when this is not the first staircasing transaction."
firststair:
cannot_be_no: "The answer to 'Is this the first staircasing transaction?' cannot be 'no' if the number of staircasing transactions is 1."

27
spec/features/schemes_spec.rb

@ -644,8 +644,8 @@ RSpec.describe "Schemes scheme Features" do
end
it "allows changing details questions" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
expect(page).to have_current_path("/schemes/#{scheme.id}/details?check_answers=true")
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
expect(page).to have_current_path("/schemes/#{scheme.id}/details?referrer=check-answers")
fill_in "Scheme name", with: "Example"
click_button "Save changes"
@ -655,14 +655,14 @@ RSpec.describe "Schemes scheme Features" do
end
it "lets me select the support answers after navigating back" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
click_link "Back"
expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers")
expect(page).to have_content "Check your changes before creating this scheme"
end
it "indicates if the scheme is not complete" do
click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true", match: :first)
click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?referrer=check-answers", match: :first)
choose "Yes"
click_button "Save changes"
visit("/schemes/#{scheme.id}/check-answers")
@ -710,8 +710,8 @@ RSpec.describe "Schemes scheme Features" do
end
it "allows changing details questions" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
expect(page).to have_current_path("/schemes/#{scheme.id}/details?check_answers=true")
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
expect(page).to have_current_path("/schemes/#{scheme.id}/details?referrer=check-answers")
fill_in "Scheme name", with: "Example"
click_button "Save changes"
@ -721,21 +721,14 @@ RSpec.describe "Schemes scheme Features" do
end
it "lets me select the support answers after navigating back" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
click_link "Back"
expect(page).to have_current_path("/schemes/#{scheme.id}/check-answers")
expect(page).to have_content "Check your changes before creating this scheme"
end
it "keeps the provider answer when switching between other provider options" do
click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true", match: :first)
choose "Yes"
click_button "Save changes"
expect(find_field("Offenders and people at risk of offending")).to be_checked
end
it "does not display the answer if it's changed to the same support provider" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
choose "The same organisation that owns the housing stock"
click_button "Save changes"
expect(page).not_to have_content("Organisation providing support")
@ -787,11 +780,11 @@ RSpec.describe "Schemes scheme Features" do
context "when I click to change scheme name" do
before do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
click_link("Change", href: "/schemes/#{scheme.id}/details?referrer=check-answers", match: :first)
end
it "shows available fields to edit" do
expect(page).to have_current_path("/schemes/#{scheme.id}/details?check_answers=true")
expect(page).to have_current_path("/schemes/#{scheme.id}/details?referrer=check-answers")
expect(page).to have_content "Scheme details"
end

29
spec/models/form/sales/pages/buyer2_relationship_to_buyer1_yes_no_spec.rb

@ -0,0 +1,29 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Buyer2RelationshipToBuyer1YesNo, 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: Time.zone.local(2025, 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[relat2])
end
it "has the correct id" do
expect(page.id).to eq("buyer_2_relationship_to_buyer_1")
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 eq([{ "joint_purchase?" => true }])
end
end

87
spec/models/form/sales/pages/person_relationship_to_buyer1_yes_no_spec.rb

@ -0,0 +1,87 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::PersonRelationshipToBuyer1YesNo, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection, person_index:) }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2025, 4, 1))) }
let(:person_index) { 1 }
let(:page_id) { "person_1_relationship_to_buyer_1" }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has the correct description" do
expect(page.description).to be_nil
end
context "with person 2" do
let(:person_index) { 2 }
let(:page_id) { "person_2_relationship_to_buyer_1" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat2])
end
it "has the correct id" do
expect(page.id).to eq("person_2_relationship_to_buyer_1")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_2" => 1 }])
end
end
context "with person 3" do
let(:person_index) { 3 }
let(:page_id) { "person_3_relationship_to_buyer_1" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat3])
end
it "has the correct id" do
expect(page.id).to eq("person_3_relationship_to_buyer_1")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_3" => 1 }])
end
end
context "with person 4" do
let(:person_index) { 4 }
let(:page_id) { "person_4_relationship_to_buyer_1" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat4])
end
it "has the correct id" do
expect(page.id).to eq("person_4_relationship_to_buyer_1")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_4" => 1 }])
end
end
context "with person 5" do
let(:person_index) { 5 }
let(:page_id) { "person_5_relationship_to_buyer_1" }
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[relat5])
end
it "has the correct id" do
expect(page.id).to eq("person_5_relationship_to_buyer_1")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "details_known_5" => 1 }])
end
end
end

43
spec/models/form/sales/questions/buyer2_relationship_to_buyer1_yes_no_spec.rb

@ -0,0 +1,43 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::Buyer2RelationshipToBuyer1YesNo, 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, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2025, 4, 1)))) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("relat2")
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?(nil)).to be false
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Buyer prefers not to say" },
})
end
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" },
])
end
end

110
spec/models/form/sales/questions/person_relationship_to_buyer1_yes_no_spec.rb

@ -0,0 +1,110 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1YesNo, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page, person_index:) }
let(:question_id) { "relat2" }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date: Time.zone.local(2025, 4, 1)))) }
let(:person_index) { 2 }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?(nil)).to be false
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"P" => { "value" => "Yes" },
"X" => { "value" => "No" },
"R" => { "value" => "Person prefers not to say" },
})
end
context "when person 2" do
let(:question_id) { "relat2" }
let(:person_index) { 2 }
it "has the correct id" do
expect(question.id).to eq("relat2")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "when person 3" do
let(:question_id) { "relat3" }
let(:person_index) { 3 }
it "has the correct id" do
expect(question.id).to eq("relat3")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat3" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "when person 4" do
let(:question_id) { "relat4" }
let(:person_index) { 4 }
it "has the correct id" do
expect(question.id).to eq("relat4")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat4" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "when person 5" do
let(:question_id) { "relat5" }
let(:person_index) { 5 }
it "has the correct id" do
expect(question.id).to eq("relat5")
end
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat5" => "R" }, "value" => "Prefers not to say" },
])
end
end
end

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

@ -5,7 +5,7 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model
let(:subsection_id) { nil }
let(:subsection_definition) { nil }
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1)) }
let(:form) { instance_double(Form, start_date: Time.zone.local(2024, 4, 1), start_year_2025_or_later?: false) }
let(:section) { instance_double(Form::Sales::Sections::SaleInformation, form:) }
it "has correct section" do
@ -83,4 +83,46 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model
expect(discounted_ownership_scheme.displayed_in_tasklist?(log)).to eq(false)
end
end
context "with form on or after 2025" do
let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 1), start_year_2025_or_later?: true) }
it "has correct pages" do
expect(discounted_ownership_scheme.pages.map(&:id)).to eq(
%w[
living_before_purchase_discounted_ownership_joint_purchase
living_before_purchase_discounted_ownership
purchase_price
discount
extra_borrowing_price_value_check
percentage_discount_value_check
grant
grant_value_check
purchase_price_discounted_ownership
discounted_sale_grant_value_check
about_price_discounted_ownership_value_check
discounted_ownership_deposit_and_mortgage_value_check_after_value_and_discount
mortgage_used_discounted_ownership
discounted_ownership_mortgage_used_mortgage_value_check
discounted_sale_mortgage_used_value_check
mortgage_amount_discounted_ownership
discounted_ownership_mortgage_amount_mortgage_value_check
discounted_sale_mortgage_value_check
extra_borrowing_mortgage_value_check
discounted_ownership_deposit_and_mortgage_value_check_after_mortgage
mortgage_length_discounted_ownership
extra_borrowing_discounted_ownership
extra_borrowing_value_check
deposit_discounted_ownership
extra_borrowing_deposit_value_check
discounted_ownership_deposit_joint_purchase_value_check
discounted_ownership_deposit_value_check
discounted_ownership_deposit_and_mortgage_value_check_after_deposit
discounted_sale_deposit_value_check
leasehold_charges_discounted_ownership
monthly_charges_discounted_ownership_value_check
],
)
end
end
end

185
spec/models/form/sales/subsections/household_characteristics_spec.rb

@ -16,10 +16,19 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
expect(household_characteristics.section).to eq(section)
end
it "has the correct id" do
expect(household_characteristics.id).to eq("household_characteristics")
end
it "has the correct label" do
expect(household_characteristics.label).to eq("Household characteristics")
end
context "with 2022/23 form" do
before do
allow(form).to receive(:start_date).and_return(Time.zone.local(2022, 4, 1))
allow(form).to receive(:start_year_2024_or_later?).and_return(false)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end
it "has correct pages" do
@ -121,6 +130,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
before do
allow(form).to receive(:start_date).and_return(Time.zone.local(2023, 4, 1))
allow(form).to receive(:start_year_2024_or_later?).and_return(false)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end
it "has correct pages" do
@ -229,6 +239,27 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
before do
allow(form).to receive(:start_date).and_return(Time.zone.local(2024, 4, 1))
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
allow(form).to receive(:start_year_2025_or_later?).and_return(false)
end
it "has correct depends on" do
expect(household_characteristics.depends_on).to eq([{ "setup_completed?" => true, "company_buyer?" => false }])
end
context "when the sale is to a company buyer" do
let(:log) { FactoryBot.build(:sales_log, ownershipsch: 3, companybuy: 1) }
it "is not displayed in tasklist" do
expect(household_characteristics.displayed_in_tasklist?(log)).to eq(false)
end
end
context "when the sale is not to a company buyer" do
let(:log) { FactoryBot.build(:sales_log, ownershipsch: 3, companybuy: 2) }
it "is displayed in tasklist" do
expect(household_characteristics.displayed_in_tasklist?(log)).to eq(true)
end
end
it "has correct pages" do
@ -358,31 +389,141 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
end
end
it "has the correct id" do
expect(household_characteristics.id).to eq("household_characteristics")
end
it "has the correct label" do
expect(household_characteristics.label).to eq("Household characteristics")
end
it "has correct depends on" do
expect(household_characteristics.depends_on).to eq([{ "setup_completed?" => true, "company_buyer?" => false }])
end
context "when the sale is to a company buyer" do
let(:log) { FactoryBot.build(:sales_log, ownershipsch: 3, companybuy: 1) }
it "is not displayed in tasklist" do
expect(household_characteristics.displayed_in_tasklist?(log)).to eq(false)
context "with 2025/26 form" do
before do
allow(form).to receive(:start_date).and_return(Time.zone.local(2025, 4, 1))
allow(form).to receive(:start_year_2024_or_later?).and_return(true)
allow(form).to receive(:start_year_2025_or_later?).and_return(true)
end
end
context "when the sale is not to a company buyer" do
let(:log) { FactoryBot.build(:sales_log, ownershipsch: 3, companybuy: 2) }
it "has correct depends on" do
expect(household_characteristics.depends_on).to eq([{ "setup_completed?" => true }])
end
it "is displayed in tasklist" do
expect(household_characteristics.displayed_in_tasklist?(log)).to eq(true)
it "has correct pages" do
expect(household_characteristics.pages.map(&:id)).to eq(
%w[
buyer_1_age
age_1_retirement_value_check
age_1_not_retired_value_check
age_1_old_persons_shared_ownership_joint_purchase_value_check
age_1_old_persons_shared_ownership_value_check
buyer_1_gender_identity
buyer_1_ethnic_group
buyer_1_ethnic_background_black
buyer_1_ethnic_background_asian
buyer_1_ethnic_background_arab
buyer_1_ethnic_background_mixed
buyer_1_ethnic_background_white
buyer_1_nationality
buyer_1_working_situation
working_situation_1_retirement_value_check
working_situation_1_not_retired_value_check
working_situation_buyer_1_income_min_value_check
buyer_1_live_in_property
buyer_1_live_in_property_value_check
buyer_2_relationship_to_buyer_1
buyer_2_relationship_student_not_child_value_check
buyer_2_age
age_2_old_persons_shared_ownership_joint_purchase_value_check
age_2_old_persons_shared_ownership_value_check
age_2_buyer_retirement_value_check
age_2_buyer_not_retired_value_check
buyer_2_age_student_not_child_value_check
buyer_2_gender_identity
buyer_2_ethnic_group
buyer_2_ethnic_background_black
buyer_2_ethnic_background_asian
buyer_2_ethnic_background_arab
buyer_2_ethnic_background_mixed
buyer_2_ethnic_background_white
buyer_2_nationality
buyer_2_working_situation
working_situation_2_retirement_value_check_joint_purchase
working_situation_2_not_retired_value_check_joint_purchase
working_situation_buyer_2_income_min_value_check
buyer_2_working_situation_student_not_child_value_check
buyer_2_live_in_property
buyer_2_live_in_property_value_check
number_of_others_in_property
number_of_others_in_property_joint_purchase
person_2_known
person_2_relationship_to_buyer_1
relationship_2_partner_under_16_value_check
relationship_2_multiple_partners_value_check
relationship_2_student_not_child_value_check
person_2_age
age_2_retirement_value_check
age_2_not_retired_value_check
age_2_student_not_child_value_check
age_2_partner_under_16_value_check
person_2_gender_identity
person_2_working_situation
working_situation_2_retirement_value_check
working_situation_2_not_retired_value_check
working_situation_2_student_not_child_value_check
person_3_known
person_3_relationship_to_buyer_1
relationship_3_partner_under_16_value_check
relationship_3_multiple_partners_value_check
relationship_3_student_not_child_value_check
person_3_age
age_3_retirement_value_check
age_3_not_retired_value_check
age_3_student_not_child_value_check
age_3_partner_under_16_value_check
person_3_gender_identity
person_3_working_situation
working_situation_3_retirement_value_check
working_situation_3_not_retired_value_check
working_situation_3_student_not_child_value_check
person_4_known
person_4_relationship_to_buyer_1
relationship_4_partner_under_16_value_check
relationship_4_multiple_partners_value_check
relationship_4_student_not_child_value_check
person_4_age
age_4_retirement_value_check
age_4_not_retired_value_check
age_4_student_not_child_value_check
age_4_partner_under_16_value_check
person_4_gender_identity
person_4_working_situation
working_situation_4_retirement_value_check
working_situation_4_not_retired_value_check
working_situation_4_student_not_child_value_check
person_5_known
person_5_relationship_to_buyer_1
relationship_5_partner_under_16_value_check
relationship_5_multiple_partners_value_check
relationship_5_student_not_child_value_check
person_5_age
age_5_retirement_value_check
age_5_not_retired_value_check
age_5_student_not_child_value_check
age_5_partner_under_16_value_check
person_5_gender_identity
person_5_working_situation
working_situation_5_retirement_value_check
working_situation_5_not_retired_value_check
working_situation_5_student_not_child_value_check
person_6_known
person_6_relationship_to_buyer_1
relationship_6_partner_under_16_value_check
relationship_6_multiple_partners_value_check
relationship_6_student_not_child_value_check
person_6_age
age_6_retirement_value_check
age_6_not_retired_value_check
age_6_student_not_child_value_check
age_6_partner_under_16_value_check
person_6_gender_identity
person_6_working_situation
working_situation_6_retirement_value_check
working_situation_6_not_retired_value_check
working_situation_6_student_not_child_value_check
],
)
end
end
end

10
spec/models/validations/sales/financial_validations_spec.rb

@ -275,18 +275,20 @@ RSpec.describe Validations::Sales::FinancialValidations do
record.stairbought = 9
[2, 16, 18, 24].each do |type|
record.type = type
shared_ownership_type = record.form.get_question("type", record).label_from_value(record.type).downcase
financial_validator.validate_percentage_bought_at_least_threshold(record)
expect(record.errors["stairbought"]).to eq([I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold: 10)])
expect(record.errors["type"]).to eq([I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold: 10)])
expect(record.errors["stairbought"]).to eq([I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold: 10, shared_ownership_type:)])
expect(record.errors["type"]).to eq([I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold: 10, shared_ownership_type:)])
record.errors.clear
end
record.stairbought = 0
[28, 30, 31, 32].each do |type|
record.type = type
shared_ownership_type = record.form.get_question("type", record).label_from_value(record.type).downcase
financial_validator.validate_percentage_bought_at_least_threshold(record)
expect(record.errors["stairbought"]).to eq([I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold: 1)])
expect(record.errors["type"]).to eq([I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold: 1)])
expect(record.errors["stairbought"]).to eq([I18n.t("validations.sales.financial.stairbought.percentage_bought_must_be_at_least_threshold", threshold: 1, shared_ownership_type:)])
expect(record.errors["type"]).to eq([I18n.t("validations.sales.financial.type.percentage_bought_must_be_at_least_threshold", threshold: 1, shared_ownership_type:)])
record.errors.clear
end
end

40
spec/models/validations/sales/sale_information_validations_spec.rb

@ -1406,4 +1406,44 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end
end
end
describe "#validate_number_of_staircase_transactions" do
let(:record) { build(:sales_log, numstair:, firststair:) }
before do
sale_information_validator.validate_number_of_staircase_transactions(record)
end
context "when it is not the first staircasing transaction" do
context "and the number of staircasing transactions is between 2 and 10" do
let(:numstair) { 6 }
let(:firststair) { 2 }
it "does not add an error" do
expect(record.errors).to be_empty
end
end
context "and the number of staircasing transactions is less than 2" do
let(:numstair) { 1 }
let(:firststair) { 2 }
it "adds an error" do
expect(record.errors[:numstair]).to include(I18n.t("validations.sales.sale_information.numstair.must_be_greater_than_one"))
expect(record.errors[:firststair]).to include(I18n.t("validations.sales.sale_information.firststair.cannot_be_no"))
end
end
end
context "when it is the first staircasing transaction" do
context "and numstair is also 1" do
let(:numstair) { 1 }
let(:firststair) { 1 }
it "does not add an error" do
expect(record.errors).to be_empty
end
end
end
end
end

42
spec/requests/schemes_controller_spec.rb

@ -1405,10 +1405,11 @@ RSpec.describe SchemesController, type: :request do
expect(scheme_to_update.reload.has_other_client_group).to eq("Yes")
end
context "when updating from check answers page with the answer YES" do
context "when updating from check answers page with the answer YES and no secondary client group set" do
let(:scheme_to_update) { create(:scheme, owning_organisation: user.organisation, confirmed: nil, secondary_client_group: nil) }
let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } }
it "renders check answers page after successful update" do
it "renders secondary client group page after successful update" do
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("What is the other client group?")
@ -1420,6 +1421,22 @@ RSpec.describe SchemesController, type: :request do
end
end
context "when updating from check answers page with the answer YES and a secondary client group set" do
let(:scheme_to_update) { create(:scheme, owning_organisation: user.organisation, confirmed: nil, secondary_client_group: "F") }
let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } }
it "renders check answers page after successful update" do
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("Check your changes before creating this scheme")
end
it "updates a scheme with valid params" do
follow_redirect!
expect(scheme_to_update.reload.has_other_client_group).to eq("Yes")
end
end
context "when updating from check answers page with the answer NO" do
let(:params) { { scheme: { has_other_client_group: "No", page: "confirm-secondary", check_answers: "true" } } }
@ -1716,10 +1733,11 @@ RSpec.describe SchemesController, type: :request do
expect(scheme_to_update.reload.has_other_client_group).to eq("Yes")
end
context "when updating from check answers page with the answer YES" do
context "when updating from check answers page with the answer YES and no existing secondary client group set" do
let(:scheme_to_update) { create(:scheme, owning_organisation: user.organisation, confirmed: nil, secondary_client_group: nil) }
let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } }
it "renders check answers page after successful update" do
it "renders secondary client group page after successful update" do
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("What is the other client group?")
@ -1731,6 +1749,22 @@ RSpec.describe SchemesController, type: :request do
end
end
context "when updating from check answers page with the answer YES and an existing secondary client group set" do
let(:scheme_to_update) { create(:scheme, owning_organisation: user.organisation, confirmed: nil, secondary_client_group: "F") }
let(:params) { { scheme: { has_other_client_group: "Yes", page: "confirm-secondary", check_answers: "true" } } }
it "renders check answers page after successful update" do
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("Check your changes before creating this scheme")
end
it "updates a scheme with valid params" do
follow_redirect!
expect(scheme_to_update.reload.has_other_client_group).to eq("Yes")
end
end
context "when updating from check answers page with the answer NO" do
let(:params) { { scheme: { has_other_client_group: "No", page: "confirm-secondary", check_answers: "true" } } }

6
yarn.lock

@ -2244,9 +2244,9 @@ cosmiconfig@^9.0.0:
parse-json "^5.2.0"
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"

Loading…
Cancel
Save