diff --git a/app/models/form/sales/pages/service_charge.rb b/app/models/form/sales/pages/service_charge.rb new file mode 100644 index 000000000..a0102eda4 --- /dev/null +++ b/app/models/form/sales/pages/service_charge.rb @@ -0,0 +1,13 @@ +class Form::Sales::Pages::ServiceCharge < ::Form::Page + def initialize(id, hsh, subsection) + super + @copy_key = "sales.sale_information.servicecharges" + end + + def questions + @questions ||= [ + Form::Sales::Questions::HasServiceCharge.new(nil, nil, self), + Form::Sales::Questions::ServiceCharge.new(nil, nil, self), + ] + end +end diff --git a/app/models/form/sales/questions/has_leasehold_charges.rb b/app/models/form/sales/questions/has_leasehold_charges.rb index c4998f590..36086ea36 100644 --- a/app/models/form/sales/questions/has_leasehold_charges.rb +++ b/app/models/form/sales/questions/has_leasehold_charges.rb @@ -2,7 +2,6 @@ class Form::Sales::Questions::HasLeaseholdCharges < ::Form::Question def initialize(id, hsh, subsection, ownershipsch:) super(id, hsh, subsection) @id = "has_mscharge" - @copy_key = "sales.sale_information.leaseholdcharges.has_mscharge" @type = "radio" @answer_options = ANSWER_OPTIONS @conditional_for = { @@ -16,6 +15,7 @@ class Form::Sales::Questions::HasLeaseholdCharges < ::Form::Question ], } @ownershipsch = ownershipsch + @copy_key = "sales.sale_information.leaseholdcharges.has_mscharge" @question_number = QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP.fetch(form.start_date.year, QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP.max_by { |k, _v| k }.last)[ownershipsch] end @@ -26,6 +26,6 @@ class Form::Sales::Questions::HasLeaseholdCharges < ::Form::Question QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP = { 2024 => { 1 => 99, 2 => 110, 3 => 117 }, - 2025 => { 1 => 88, 2 => 111 }, + 2025 => { 2 => 111 }, }.freeze end diff --git a/app/models/form/sales/questions/has_service_charge.rb b/app/models/form/sales/questions/has_service_charge.rb new file mode 100644 index 000000000..41bf5f809 --- /dev/null +++ b/app/models/form/sales/questions/has_service_charge.rb @@ -0,0 +1,27 @@ +class Form::Sales::Questions::HasServiceCharge < ::Form::Question + def initialize(id, hsh, subsection) + super + @id = "has_mscharge" + @type = "radio" + @answer_options = ANSWER_OPTIONS + @conditional_for = { + "mscharge" => [1], + } + @hidden_in_check_answers = { + "depends_on" => [ + { + "has_mscharge" => 1, + }, + ], + } + @copy_key = "sales.sale_information.servicecharges.has_servicecharge" + @question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max] + end + + ANSWER_OPTIONS = { + "1" => { "value" => "Yes" }, + "0" => { "value" => "No" }, + }.freeze + + QUESTION_NUMBER_FROM_YEAR = { 2025 => 88 }.freeze +end diff --git a/app/models/form/sales/questions/leasehold_charges.rb b/app/models/form/sales/questions/leasehold_charges.rb index 41eb26bcd..453c2fd86 100644 --- a/app/models/form/sales/questions/leasehold_charges.rb +++ b/app/models/form/sales/questions/leasehold_charges.rb @@ -2,12 +2,12 @@ class Form::Sales::Questions::LeaseholdCharges < ::Form::Question def initialize(id, hsh, subsection, ownershipsch:) super(id, hsh, subsection) @id = "mscharge" - @copy_key = "sales.sale_information.leaseholdcharges.mscharge" @type = "numeric" @min = 1 @step = 0.01 @width = 5 @prefix = "£" + @copy_key = "sales.sale_information.leaseholdcharges.mscharge" @ownershipsch = ownershipsch @question_number = QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP.fetch(form.start_date.year, QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP.max_by { |k, _v| k }.last)[ownershipsch] end @@ -15,6 +15,6 @@ class Form::Sales::Questions::LeaseholdCharges < ::Form::Question QUESTION_NUMBER_FROM_YEAR_AND_OWNERSHIP = { 2023 => { 1 => 98, 2 => 109, 3 => 117 }, 2024 => { 1 => 99, 2 => 110, 3 => 117 }, - 2025 => { 1 => 88, 2 => 111 }, + 2025 => { 2 => 111 }, }.freeze end diff --git a/app/models/form/sales/questions/service_charge.rb b/app/models/form/sales/questions/service_charge.rb new file mode 100644 index 000000000..70fa6cc72 --- /dev/null +++ b/app/models/form/sales/questions/service_charge.rb @@ -0,0 +1,15 @@ +class Form::Sales::Questions::ServiceCharge < ::Form::Question + def initialize(id, hsh, subsection) + super + @id = "mscharge" + @type = "numeric" + @min = 1 + @step = 0.01 + @width = 5 + @prefix = "£" + @copy_key = "sales.sale_information.servicecharges.servicecharge" + @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 => 88 }.freeze +end diff --git a/app/models/form/sales/subsections/shared_ownership_initial_purchase.rb b/app/models/form/sales/subsections/shared_ownership_initial_purchase.rb index 175994b0b..4bfb10f2d 100644 --- a/app/models/form/sales/subsections/shared_ownership_initial_purchase.rb +++ b/app/models/form/sales/subsections/shared_ownership_initial_purchase.rb @@ -37,7 +37,7 @@ class Form::Sales::Subsections::SharedOwnershipInitialPurchase < ::Form::Subsect Form::Sales::Pages::DepositDiscount.new("deposit_discount_optional", nil, self, optional: true), 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, ownershipsch: 1), + Form::Sales::Pages::ServiceCharge.new("service_charge", nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_shared_ownership_value_check", nil, self), Form::Sales::Pages::EstateManagementFee.new("estate_management_fee", nil, self), ].compact diff --git a/config/locales/forms/2025/sales/sale_information.en.yml b/config/locales/forms/2025/sales/sale_information.en.yml index 95eed6185..147d10438 100644 --- a/config/locales/forms/2025/sales/sale_information.en.yml +++ b/config/locales/forms/2025/sales/sale_information.en.yml @@ -248,16 +248,29 @@ en: leaseholdcharges: page_header: "" has_mscharge: - check_answer_label: "Property service charges" - check_answer_prompt: "Enter service charges if any" + check_answer_label: "Property leasehold charges" + check_answer_prompt: "Enter leasehold charges if any" hint_text: "For example, service and management charges" - question_text: "Does the property have any service charges?" + question_text: "Does the property have any monthly leasehold charges?" mscharge: check_answer_label: "Monthly leasehold charges" check_answer_prompt: "" hint_text: "" question_text: "Enter the total monthly charge" + servicecharges: + page_header: "" + has_servicecharge: + check_answer_label: "Property service charges" + check_answer_prompt: "Enter service charges if any" + hint_text: "This includes any charges for day-to-day maintenance and repairs, building insurance, and any contributions to a sinking or reserved fund. It does not include estate management fees." + question_text: "Does the property have any service charges?" + servicecharge: + check_answer_label: "Monthly service charges" + check_answer_prompt: "" + hint_text: "" + question_text: "Enter the total monthly charge" + purchase_price: discounted_ownership: page_header: "About the price of the property" diff --git a/spec/models/form/sales/pages/service_charge_spec.rb b/spec/models/form/sales/pages/service_charge_spec.rb new file mode 100644 index 000000000..ec23d9876 --- /dev/null +++ b/spec/models/form/sales/pages/service_charge_spec.rb @@ -0,0 +1,29 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::ServiceCharge, 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(2023, 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[has_mscharge mscharge]) + end + + it "has the correct id" do + expect(page.id).to eq(nil) + end + + it "has the correct description" do + expect(page.description).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to be_nil + end +end diff --git a/spec/models/form/sales/questions/has_service_charge_spec.rb b/spec/models/form/sales/questions/has_service_charge_spec.rb new file mode 100644 index 000000000..bf0bd9d25 --- /dev/null +++ b/spec/models/form/sales/questions/has_service_charge_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::HasServiceCharge, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:form) { instance_double(Form, start_date: Time.zone.local(2025, 4, 4)) } + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page, subsection: instance_double(Form::Subsection, id: "shared_ownership", form:)) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("has_mscharge") + 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({ + "0" => { "value" => "No" }, + "1" => { "value" => "Yes" }, + }) + end + + it "has correct conditional for" do + expect(question.conditional_for).to eq({ + "mscharge" => [1], + }) + end + + it "has correct hidden_in_check_answers for" do + expect(question.hidden_in_check_answers).to eq({ + "depends_on" => [ + { + "has_mscharge" => 1, + }, + ], + }) + end +end diff --git a/spec/models/form/sales/questions/service_charge_spec.rb b/spec/models/form/sales/questions/service_charge_spec.rb new file mode 100644 index 000000000..56dee01cf --- /dev/null +++ b/spec/models/form/sales/questions/service_charge_spec.rb @@ -0,0 +1,37 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::ServiceCharge, 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(2023, 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("mscharge") + end + + it "has the correct type" do + expect(question.type).to eq("numeric") + end + + it "is not marked as derived" do + expect(question.derived?(nil)).to be false + end + + it "has the correct width" do + expect(question.width).to be 5 + end + + it "has the correct min" do + expect(question.min).to be 1 + end + + it "has the correct prefix" do + expect(question.prefix).to eq("£") + end +end diff --git a/spec/models/form/sales/subsections/shared_ownership_initial_purchase_spec.rb b/spec/models/form/sales/subsections/shared_ownership_initial_purchase_spec.rb index 3e473a162..2f6c8f034 100644 --- a/spec/models/form/sales/subsections/shared_ownership_initial_purchase_spec.rb +++ b/spec/models/form/sales/subsections/shared_ownership_initial_purchase_spec.rb @@ -46,7 +46,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipInitialPurchase, type: : deposit_discount_optional shared_ownership_deposit_value_check monthly_rent - leasehold_charges_shared_ownership + service_charge monthly_charges_shared_ownership_value_check estate_management_fee ],