Skip to content

Commit

Permalink
[CRIMAPP-1516] Property ownership validation (#1303)
Browse files Browse the repository at this point in the history
  • Loading branch information
EdwinKruglov authored Jan 10, 2025
1 parent d203445 commit def1beb
Show file tree
Hide file tree
Showing 20 changed files with 407 additions and 8 deletions.
1 change: 0 additions & 1 deletion app/controllers/steps/capital/saving_type_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ def additional_permitted_params
end

def require_no_savings
# pp current_crime_application.capital.savings
return true if current_crime_application.capital.savings.empty?

redirect_to edit_steps_capital_savings_summary_path(current_crime_application)
Expand Down
21 changes: 21 additions & 0 deletions app/controllers/steps/capital/usual_property_details_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module Steps
module Capital
class UsualPropertyDetailsController < Steps::CapitalStepController
def edit
@form_object = UsualPropertyDetailsForm.build(
current_crime_application
)
end

def update
update_and_advance(UsualPropertyDetailsForm, as: :usual_property_details)
end

private

def additional_permitted_params
[:action]
end
end
end
end
32 changes: 32 additions & 0 deletions app/forms/steps/capital/usual_property_details_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Steps
module Capital
class UsualPropertyDetailsForm < Steps::BaseFormObject
attr_accessor :action

validates :action, presence: true
validates :action, inclusion: { in: :choices }

def choices
UsualPropertyDetailsAnswer.values
end

def home_address
crime_application.applicant.home_address.values_at(
*::Address::ADDRESS_ATTRIBUTES
).compact_blank.join("\r\n")
end

def residence_ownership
crime_application.applicant.residence_type
end

private

# :nocov:
def persist!
true
end
# :nocov:
end
end
end
14 changes: 14 additions & 0 deletions app/models/capital.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ def partner_has_premium_bonds
super if requires_full_capital?
end

def usual_property_details_required?
return false unless FeatureFlags.property_ownership_validation.enabled?
return false unless requires_full_capital?

residence_type = ResidenceType.new(crime_application.applicant.residence_type)
if residence_type.owned?
return false if residence_type == ResidenceType::PARTNER_OWNED && !MeansStatus.include_partner?(crime_application)

return crime_application.properties.home_address.blank?
end

false
end

private

def confirmation_validator
Expand Down
21 changes: 19 additions & 2 deletions app/services/decisions/capital_decision_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ def destination
after_properties_summary
when :property_type
after_property_type(form_object.property)
when :usual_property_details
after_usual_property_details
when :residential_property, :commercial_property, :land
after_properties
when :property_address
Expand Down Expand Up @@ -97,7 +99,7 @@ def after_investments_summary
end

def after_properties_summary
return edit(:saving_type) if form_object.add_property.no?
return no_property_path if form_object.add_property.no?

edit(:other_property_type)
end
Expand All @@ -117,7 +119,7 @@ def after_trust_fund
end

def after_property_type(property)
return edit(:saving_type) unless property
return no_property_path unless property

redirect_path = if property.property_type == PropertyType::LAND.to_s
property.property_type.to_sym
Expand All @@ -128,6 +130,21 @@ def after_property_type(property)
edit(redirect_path, property_id: property)
end

def no_property_path
return edit(:usual_property_details) if crime_application.capital.usual_property_details_required?

edit(:saving_type)
end

def after_usual_property_details
if form_object.action == UsualPropertyDetailsAnswer::CHANGE_ANSWER.to_s
return edit('/steps/client/residence_type')
end

edit(:residential_property,
property_id: crime_application.properties.create!(property_type: PropertyType::RESIDENTIAL.to_s))
end

# TODO: : Fix nested conditions
def after_properties
return edit(:property_address) if form_object.is_home_address.nil? || form_object.is_home_address.no?
Expand Down
5 changes: 5 additions & 0 deletions app/validators/capital_assessment/answers_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def validate # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Me
errors.add :national_savings_certificates, :incomplete_records unless national_savings_certificates_complete?
errors.add :investment_type, :blank unless investment_type_complete?
errors.add :investments, :incomplete_records unless investments_complete?
errors.add :usual_property_details, :blank unless usual_property_details_complete?
end

errors.add :trust_fund, :blank unless trust_fund_complete?
Expand Down Expand Up @@ -111,5 +112,9 @@ def partner_trust_fund_complete?
def frozen_income_savings_assets_complete?
record.has_frozen_income_or_assets.present? || income&.has_frozen_income_or_assets.present?
end

def usual_property_details_complete?
!record.usual_property_details_required?
end
end
end
8 changes: 8 additions & 0 deletions app/value_objects/residence_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ class ResidenceType < ValueObject
SOMEONE_ELSE = new(:someone_else),
NONE = new(:none),
].freeze

def owned?
[
APPLICANT_OWNED,
PARTNER_OWNED,
JOINT_OWNED
].include?(self)
end
end
6 changes: 6 additions & 0 deletions app/value_objects/usual_property_details_answer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class UsualPropertyDetailsAnswer < ValueObject
VALUES = [
PROVIDE_DETAILS = new(:provide_details),
CHANGE_ANSWER = new(:change_answer)
].freeze
end
22 changes: 22 additions & 0 deletions app/views/steps/capital/usual_property_details/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<% title t('.heading', residence_ownership: t(".residence_ownership.#{@form_object.residence_ownership}")) %>
<% step_header %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= govuk_error_summary(@form_object) %>

<span class="govuk-caption-xl"><%= t('steps.capital.caption') %></span>

<h1 class="govuk-heading-xl">
<%= t('.heading', residence_ownership: t(".residence_ownership.#{@form_object.residence_ownership}")) %>
</h1>

<p class="govuk-body"><%= t('.info', residence_ownership: t(".residence_ownership.#{@form_object.residence_ownership}")) %></p>
<%= simple_format(@form_object.home_address, class: 'govuk-body') %>

<%= step_form @form_object do |f| %>
<%= f.govuk_collection_radio_buttons :action, @form_object.choices, :value %>
<%= f.continue_button %>
<% end %>
</div>
</div>
4 changes: 4 additions & 0 deletions config/locales/en/errors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,10 @@ en:
attributes:
property_type:
blank: Select which assets %{subject} owns or part-owns inside or outside the UK, or select 'They do not own any of these assets'
steps/capital/usual_property_details_form:
attributes:
action:
blank: Select what you want to do next
steps/capital/saving_type_form:
attributes:
saving_type:
Expand Down
6 changes: 6 additions & 0 deletions config/locales/en/helpers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ en:
heading: You cannot submit this application yet, as we cannot check %{subject}'s benefit status without their National Insurance number
steps_capital_property_type_form:
property_type: Which assets does %{subject} own or part-own inside or outside the UK?
steps_capital_usual_property_details_form:
action: What do you want to do next?
steps_capital_other_property_type_form:
property_type: Which other assets does %{subject} own or part-own inside or outside the UK?
steps_capital_saving_type_form:
Expand Down Expand Up @@ -1130,6 +1132,10 @@ en:
none: They do not own any of these assets
steps_capital_other_property_type_form:
property_type_options: *PROPERTY_TYPE_OPTIONS
steps_capital_usual_property_details_form:
action_options:
provide_details: Provide the details of this property
change_answer: Change answer to where your client usually lives
steps_capital_saving_type_form:
saving_type_options: &SAVING_TYPE_OPTIONS
bank: Bank accounts
Expand Down
9 changes: 9 additions & 0 deletions config/locales/en/steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,15 @@ en:
edit:
page_title: Check your answers - Your client's capital
heading: Check your answers

usual_property_details:
edit:
heading: You need to give the details about the property your client usually lives in and that %{residence_ownership}
info: "You told us your client usually lives in a property %{residence_ownership}:"
residence_ownership:
applicant_owned: they own
partner_owned: their partner owns
joint_owned: they and their partner own

evidence:
upload:
Expand Down
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ def show_step(name)

namespace :capital do
edit_step :which_assets_owned, alias: :property_type
if FeatureFlags.property_ownership_validation.enabled?
edit_step :usual_property_details
end
crud_step :residential_property, alias: :residential_property, param: :property_id
crud_step :commercial_property, alias: :commercial_property, param: :property_id
crud_step :land, alias: :land, param: :property_id
Expand Down
4 changes: 4 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ feature_flags:
local: true
staging: true
production: false
property_ownership_validation:
local: false
staging: true
production: false

# NOTE: consider if the setting you are adding here
# should belong in the k8s `config_map`, which is
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require 'rails_helper'

RSpec.describe Steps::Capital::UsualPropertyDetailsController, type: :controller do
it_behaves_like 'a generic step controller', Steps::Capital::UsualPropertyDetailsForm,
Decisions::CapitalDecisionTree
end
59 changes: 59 additions & 0 deletions spec/forms/steps/capital/usual_property_details_form_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require 'rails_helper'

RSpec.describe Steps::Capital::UsualPropertyDetailsForm do
subject(:form) { described_class.new(crime_application:) }

let(:applicant) { instance_double(Applicant, home_address:, residence_type:) }
let(:home_address) { nil }
let(:residence_type) { nil }
let(:capital) { instance_double(Capital) }
let(:crime_application) { instance_double(CrimeApplication, applicant:, capital:) }

describe 'validations' do
it { is_expected.to validate_presence_of(:action, :blank, 'Select what you want to do next') }

context 'when the action is an invalid option' do
before { form.action = 'invalid_option' }

it 'raises an inclusion error' do
expect(form).not_to be_valid
expect(form.errors.of_kind?(:action, :inclusion)).to be(true)
end
end
end

describe '#choices' do
it { expect(form.choices).to eq(UsualPropertyDetailsAnswer.values) }
end

describe '#home_address' do
let(:home_address) {
HomeAddress.new(address_line_one: '1 Test Road', city: 'London', postcode: 'SW1 1RT',
country: 'United Kingdom')
}

it "returns client's formatted home address" do
expect(form.home_address).to eq("1 Test Road\r\nLondon\r\nSW1 1RT\r\nUnited Kingdom")
end
end

describe '#residence_ownership' do
context 'when the residence is owned by the client' do
let(:residence_type) { ResidenceType::APPLICANT_OWNED.to_s }

it { expect(form.residence_ownership).to eq(ResidenceType::APPLICANT_OWNED.to_s) }
end

context 'when the residence is owned by the partner' do
let(:residence_type) { ResidenceType::PARTNER_OWNED.to_s }

it { expect(form.residence_ownership).to eq(ResidenceType::PARTNER_OWNED.to_s) }
end

context 'when the residence is joint owned by the client and the partner' do
let(:residence_type) { ResidenceType::JOINT_OWNED.to_s }

it { expect(form.residence_ownership).to eq(ResidenceType::JOINT_OWNED.to_s) }
end
end
end
Loading

0 comments on commit def1beb

Please sign in to comment.