Browse Source

Merge branch 'main' into CLDC-1726-support-schemes-tab-logic

pull/1190/head
natdeanlewissoftwire 3 years ago
parent
commit
a1da8ab587
  1. 8
      app/components/bulk_upload_error_row_component.rb
  2. 2
      app/components/log_summary_component.html.erb
  3. 4
      app/controllers/organisations_controller.rb
  4. 59
      app/controllers/schemes_controller.rb
  5. 5
      app/helpers/filters_helper.rb
  6. 6
      app/helpers/schemes_helper.rb
  7. 73
      app/models/derived_variables/sales_log_variables.rb
  8. 1
      app/models/form/lettings/questions/renewal.rb
  9. 4
      app/models/form/sales/pages/about_deposit_without_discount.rb
  10. 1
      app/models/form/sales/pages/about_price_not_rtb.rb
  11. 17
      app/models/form/sales/pages/extra_borrowing.rb
  12. 17
      app/models/form/sales/pages/mortgage_lender.rb
  13. 17
      app/models/form/sales/pages/mortgage_lender_other.rb
  14. 7
      app/models/form/sales/pages/mortgage_length.rb
  15. 13
      app/models/form/sales/pages/postcode.rb
  16. 3
      app/models/form/sales/pages/property_local_authority.rb
  17. 5
      app/models/form/sales/pages/purchase_price.rb
  18. 5
      app/models/form/sales/questions/deposit_amount.rb
  19. 18
      app/models/form/sales/questions/extra_borrowing.rb
  20. 58
      app/models/form/sales/questions/mortgage_lender.rb
  21. 10
      app/models/form/sales/questions/mortgage_lender_other.rb
  22. 21
      app/models/form/sales/questions/postcode.rb
  23. 28
      app/models/form/sales/questions/postcode_known.rb
  24. 4
      app/models/form/sales/subsections/discounted_ownership_scheme.rb
  25. 5
      app/models/form/sales/subsections/outright_sale.rb
  26. 1
      app/models/form/sales/subsections/property_information.rb
  27. 3
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  28. 8
      app/models/lettings_log.rb
  29. 4
      app/models/log.rb
  30. 4
      app/models/organisation.rb
  31. 23
      app/models/sales_log.rb
  32. 11
      app/models/scheme.rb
  33. 2
      app/models/user.rb
  34. 8
      app/models/validations/property_validations.rb
  35. 8
      app/models/validations/shared_validations.rb
  36. 4
      app/services/bulk_upload/lettings/validator.rb
  37. 2
      app/services/csv/lettings_log_csv_service.rb
  38. 16
      app/services/imports/scheme_import_service.rb
  39. 1
      app/services/imports/scheme_location_import_service.rb
  40. 7
      app/views/form/guidance/_mortgage_lender.html.erb
  41. 4
      app/views/logs/_log_filters.erb
  42. 5
      app/views/schemes/check_answers.html.erb
  43. 2
      app/views/schemes/primary_client_group.html.erb
  44. 34
      app/views/schemes/support_services_provider.html.erb
  45. 2
      config/locales/en.yml
  46. 8
      db/migrate/20230109144039_add_mortgage_lender.rb
  47. 7
      db/migrate/20230109170748_add_extrabor_to_sales.rb
  48. 11
      db/migrate/20230111134640_remove_managing_organisation_id_from_schemes.rb
  49. 10
      db/migrate/20230113091706_add_derived_household_fields.rb
  50. 11
      db/migrate/20230113125117_add_postcode_fields_to_sales.rb
  51. 29
      db/schema.rb
  52. 3
      db/seeds.rb
  53. 16
      spec/components/bulk_upload_error_row_component_spec.rb
  54. 6
      spec/factories/sales_log.rb
  55. 1
      spec/factories/scheme.rb
  56. 2
      spec/features/form/accessible_autocomplete_spec.rb
  57. 16
      spec/features/schemes_helpers.rb
  58. 60
      spec/features/schemes_spec.rb
  59. 4
      spec/fixtures/files/lettings_logs_download.csv
  60. 4
      spec/fixtures/files/lettings_logs_download_non_support.csv
  61. 35
      spec/helpers/filters_helper_spec.rb
  62. 3
      spec/helpers/schemes_helper_spec.rb
  63. 2
      spec/models/form/lettings/questions/renewal_spec.rb
  64. 2
      spec/models/form/lettings/questions/scheme_id_spec.rb
  65. 4
      spec/models/form/sales/pages/about_deposit_without_discount_spec.rb
  66. 1
      spec/models/form/sales/pages/about_price_not_rtb_spec.rb
  67. 35
      spec/models/form/sales/pages/extra_borrowing_spec.rb
  68. 35
      spec/models/form/sales/pages/mortgage_lender_other_spec.rb
  69. 35
      spec/models/form/sales/pages/mortgage_lender_spec.rb
  70. 4
      spec/models/form/sales/pages/mortgage_length_spec.rb
  71. 33
      spec/models/form/sales/pages/postcode_spec.rb
  72. 6
      spec/models/form/sales/pages/property_local_authority_spec.rb
  73. 7
      spec/models/form/sales/pages/purchase_price_spec.rb
  74. 4
      spec/models/form/sales/questions/deposit_amount_spec.rb
  75. 49
      spec/models/form/sales/questions/extra_borrowing_spec.rb
  76. 37
      spec/models/form/sales/questions/mortgage_lender_other_spec.rb
  77. 88
      spec/models/form/sales/questions/mortgage_lender_spec.rb
  78. 59
      spec/models/form/sales/questions/postcode_known_spec.rb
  79. 58
      spec/models/form/sales/questions/postcode_spec.rb
  80. 4
      spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb
  81. 5
      spec/models/form/sales/subsections/outright_sale_spec.rb
  82. 1
      spec/models/form/sales/subsections/property_information_spec.rb
  83. 3
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  84. 4
      spec/models/form_handler_spec.rb
  85. 6
      spec/models/organisation_spec.rb
  86. 141
      spec/models/sales_log_spec.rb
  87. 20
      spec/models/user_spec.rb
  88. 2
      spec/requests/form_controller_spec.rb
  89. 43
      spec/requests/schemes_controller_spec.rb
  90. 9
      spec/services/bulk_upload/lettings/validator_spec.rb
  91. 1
      spec/services/csv/lettings_log_csv_service_spec.rb
  92. 5
      spec/services/imports/scheme_import_service_spec.rb

8
app/components/bulk_upload_error_row_component.rb

@ -2,7 +2,7 @@ class BulkUploadErrorRowComponent < ViewComponent::Base
attr_reader :bulk_upload_errors
def initialize(bulk_upload_errors:)
@bulk_upload_errors = bulk_upload_errors
@bulk_upload_errors = sorted_errors(bulk_upload_errors)
super
end
@ -45,4 +45,10 @@ class BulkUploadErrorRowComponent < ViewComponent::Base
def sales?
bulk_upload.log_type == "sales"
end
private
def sorted_errors(errors)
errors.sort_by { |e| e.cell.rjust(3, "0") }
end
end

2
app/components/log_summary_component.html.erb

@ -36,7 +36,7 @@
</p>
<% end %>
<% if current_user.support? %>
<% if current_user.support? || current_user.organisation.has_managing_agents? %>
<% if log.owning_organisation or log.managing_organisation %>
<dl class="app-metadata">
<div class="app-metadata__item">

4
app/controllers/organisations_controller.rb

@ -6,8 +6,8 @@ class OrganisationsController < ApplicationController
before_action :authenticate_user!
before_action :find_resource, except: %i[index new create]
before_action :authenticate_scope!, except: [:index]
before_action -> { session_filters(specific_org: true) }, if: -> { current_user.support? }
before_action :set_session_filters, if: -> { current_user.support? }
before_action -> { session_filters(specific_org: true) }, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }
before_action :set_session_filters, if: -> { current_user.support? || current_user.organisation.has_managing_agents? }
def index
redirect_to organisation_path(current_user.organisation) unless current_user.support?

59
app/controllers/schemes_controller.rb

@ -92,14 +92,12 @@ class SchemesController < ApplicationController
validation_errors scheme_params
if @scheme.errors.empty? && @scheme.save
if @scheme.arrangement_type_before_type_cast == "D"
redirect_to scheme_primary_client_group_path(@scheme)
else
redirect_to scheme_support_services_provider_path(@scheme)
end
redirect_to scheme_primary_client_group_path(@scheme)
else
@scheme.errors.add(:owning_organisation_id, message: @scheme.errors[:organisation])
@scheme.errors.delete(:owning_organisation)
if @scheme.errors.any? { |error| error.attribute == :owning_organisation }
@scheme.errors.add(:owning_organisation_id, message: @scheme.errors[:organisation])
@scheme.errors.delete(:owning_organisation)
end
render :new, status: :unprocessable_entity
end
end
@ -182,12 +180,6 @@ class SchemesController < ApplicationController
render "schemes/edit_name"
end
def support_services_provider
render_not_found and return unless @scheme
render "schemes/support_services_provider"
end
private
def validation_errors(scheme_params)
@ -196,10 +188,6 @@ private
@scheme.errors.add(key.to_sym)
end
end
if @scheme.arrangement_type_same? && arrangement_type_value(scheme_params[:arrangement_type]) != "D"
@scheme.errors.delete(:managing_organisation_id)
end
end
def confirm_secondary_page?(page)
@ -209,8 +197,6 @@ private
def current_template(page)
if page.include?("primary")
"schemes/primary_client_group"
elsif page.include?("support-services-provider")
"schemes/support_services_provider"
elsif page.include?("confirm")
"schemes/confirm_secondary"
elsif page.include?("secondary-client")
@ -228,8 +214,6 @@ private
def next_page_path(page)
case page
when "support-services-provider"
scheme_primary_client_group_path(@scheme)
when "primary-client-group"
scheme_confirm_secondary_client_group_path(@scheme)
when "confirm-secondary"
@ -239,13 +223,7 @@ private
when "support"
scheme_check_answers_path(@scheme)
when "details"
if @scheme.arrangement_type_before_type_cast == "D"
scheme_primary_client_group_path(@scheme)
elsif @scheme.arrangement_type.present? && @scheme.arrangement_type_before_type_cast != "D"
scheme_support_services_provider_path(@scheme)
else
scheme_details_path(@scheme)
end
scheme_primary_client_group_path(@scheme)
when "edit-name"
scheme_check_answers_path(@scheme)
when "check-answers"
@ -257,7 +235,6 @@ private
required_params = params.require(:scheme).permit(:service_name,
:sensitive,
:owning_organisation_id,
:managing_organisation_id,
:scheme_type,
:registered_under_care_act,
:id,
@ -269,14 +246,6 @@ private
:intended_stay,
:confirmed)
if arrangement_type_changed_to_different_org?(required_params)
required_params[:managing_organisation_id] = nil
end
if arrangement_type_set_to_same_org?(required_params)
required_params[:managing_organisation_id] = required_params[:owning_organisation_id] || @scheme.owning_organisation_id
end
required_params[:sensitive] = required_params[:sensitive].to_i if required_params[:sensitive]
if current_user.data_coordinator?
@ -285,22 +254,6 @@ private
required_params
end
def arrangement_type_set_to_same_org?(required_params)
return unless @scheme
arrangement_type_value(required_params[:arrangement_type]) == "D" || (required_params[:arrangement_type].blank? && @scheme.arrangement_type_same?)
end
def arrangement_type_changed_to_different_org?(required_params)
return unless @scheme
@scheme.arrangement_type_same? && arrangement_type_value(required_params[:arrangement_type]) != "D" && required_params[:managing_organisation_id].blank?
end
def arrangement_type_value(key)
key.present? ? Scheme::ARRANGEMENT_TYPE[key.to_sym] : nil
end
def search_term
params["search"]
end

5
app/helpers/filters_helper.rb

@ -22,4 +22,9 @@ module FiltersHelper
JSON.parse(session[:logs_filters])[filter] || ""
end
def organisations_filter_options(user)
organisation_options = user.support? ? Organisation.all : [user.organisation] + user.organisation.managing_agents
[OpenStruct.new(id: "", name: "Select an option")] + organisation_options.map { |org| OpenStruct.new(id: org.id, name: org.name) }
end
end

6
app/helpers/schemes_helper.rb

@ -8,7 +8,6 @@ module SchemesHelper
{ name: "Registered under Care Standards Act 2000", value: scheme.registered_under_care_act },
{ name: "Housing stock owned by", value: scheme.owning_organisation.name, edit: true },
{ name: "Support services provided by", value: scheme.arrangement_type },
{ name: "Organisation providing support", value: scheme.managing_organisation&.name },
{ name: "Primary client group", value: scheme.primary_client_group },
{ name: "Has another client group", value: scheme.has_other_client_group },
{ name: "Secondary client group", value: scheme.secondary_client_group },
@ -25,9 +24,10 @@ module SchemesHelper
base_attributes.delete_if { |item| item[:name] == "Housing stock owned by" }
end
if scheme.arrangement_type_same?
base_attributes.delete_if { |item| item[:name] == "Organisation providing support" }
if scheme.has_other_client_group == "Yes"
base_attributes.append
end
base_attributes
end

73
app/models/derived_variables/sales_log_variables.rb

@ -15,5 +15,78 @@ module DerivedVariables::SalesLogVariables
if mscharge_known.present? && mscharge_known.zero?
self.mscharge = 0
end
self.pcode1, self.pcode2 = postcode_full.split(" ") if postcode_full.present?
self.totchild = total_child
self.totadult = total_adult + total_elder
self.hhmemb = totchild + totadult
self.hhtype = household_type
end
private
def total_elder
ages = [age1, age2, age3, age4, age5, age6]
ages.count { |age| age.present? && age >= 60 }
end
def total_child
(2..6).count do |i|
age = public_send("age#{i}")
relat = public_send("relat#{i}")
age.present? && (age < 20 && %w[C].include?(relat) || age < 18)
end
end
def total_adult
total = age1.present? && age1.between?(16, 59) ? 1 : 0
total + (2..6).count do |i|
age = public_send("age#{i}")
relat = public_send("relat#{i}")
age.present? && (age.between?(20, 59) || age.between?(18, 19) && relat != "C")
end
end
def household_type
return unless total_elder && total_adult && totchild
if only_one_elder?
1
elsif only_two_elders?
2
elsif only_one_adult?
3
elsif only_two_adults?
4
elsif one_adult_with_at_least_one_child?
5
elsif at_least_two_adults_with_at_least_one_child?
6
else
9
end
end
def at_least_two_adults_with_at_least_one_child?
total_elder.zero? && total_adult >= 2 && totchild >= 1
end
def one_adult_with_at_least_one_child?
total_elder.zero? && total_adult == 1 && totchild >= 1
end
def only_two_adults?
total_elder.zero? && total_adult == 2 && totchild.zero?
end
def only_one_adult?
total_elder.zero? && total_adult == 1 && totchild.zero?
end
def only_two_elders?
total_elder == 2 && total_adult.zero? && totchild.zero?
end
def only_one_elder?
total_elder == 1 && total_adult.zero? && totchild.zero?
end
end

1
app/models/form/lettings/questions/renewal.rb

@ -6,6 +6,7 @@ class Form::Lettings::Questions::Renewal < ::Form::Question
@header = "Is this letting a renewal?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@hint_text = "A renewal is a letting to the same tenant in the same property"
end
ANSWER_OPTIONS = {

4
app/models/form/sales/pages/about_deposit_without_discount.rb

@ -2,7 +2,9 @@ class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page
def initialize(id, hsh, subsection)
super
@header = "About the deposit"
@depends_on = [{ "is_type_discount?" => false }]
@depends_on = [{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }]
end
def questions

1
app/models/form/sales/pages/about_price_not_rtb.rb

@ -5,6 +5,7 @@ class Form::Sales::Pages::AboutPriceNotRtb < ::Form::Page
@header = "About the price of the property"
@depends_on = [{
"right_to_buy?" => false,
"rent_to_buy_full_ownership?" => false,
}]
end

17
app/models/form/sales/pages/extra_borrowing.rb

@ -0,0 +1,17 @@
class Form::Sales::Pages::ExtraBorrowing < ::Form::Page
def initialize(id, hsh, subsection)
super
@header = ""
@description = ""
@subsection = subsection
@depends_on = [{
"mortgageused" => 1,
}]
end
def questions
@questions ||= [
Form::Sales::Questions::ExtraBorrowing.new(nil, nil, self),
]
end
end

17
app/models/form/sales/pages/mortgage_lender.rb

@ -0,0 +1,17 @@
class Form::Sales::Pages::MortgageLender < ::Form::Page
def initialize(id, hsh, subsection)
super
@header = ""
@description = ""
@subsection = subsection
@depends_on = [{
"mortgageused" => 1,
}]
end
def questions
@questions ||= [
Form::Sales::Questions::MortgageLender.new(nil, nil, self),
]
end
end

17
app/models/form/sales/pages/mortgage_lender_other.rb

@ -0,0 +1,17 @@
class Form::Sales::Pages::MortgageLenderOther < ::Form::Page
def initialize(id, hsh, subsection)
super
@header = ""
@description = ""
@subsection = subsection
@depends_on = [{
"mortgagelender" => 40,
}]
end
def questions
@questions ||= [
Form::Sales::Questions::MortgageLenderOther.new(nil, nil, self),
]
end
end

7
app/models/form/sales/pages/mortgage_length.rb

@ -1,4 +1,11 @@
class Form::Sales::Pages::MortgageLength < ::Form::Page
def initialize(id, hsh, subsection)
super
@depends_on = [{
"mortgageused" => 1,
}]
end
def questions
@questions ||= [
Form::Sales::Questions::MortgageLength.new(nil, nil, self),

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

@ -0,0 +1,13 @@
class Form::Sales::Pages::Postcode < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_postcode"
end
def questions
@questions ||= [
Form::Sales::Questions::PostcodeKnown.new(nil, nil, self),
Form::Sales::Questions::Postcode.new(nil, nil, self),
]
end
end

3
app/models/form/sales/pages/property_local_authority.rb

@ -2,6 +2,9 @@ class Form::Sales::Pages::PropertyLocalAuthority < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "property_local_authority"
@depends_on = [{
"is_la_inferred" => false,
}]
end
def questions

5
app/models/form/sales/pages/purchase_price.rb

@ -1,7 +1,10 @@
class Form::Sales::Pages::PurchasePrice < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "purchase_price"
@depends_on = [
{ "ownershipsch" => 3 },
{ "rent_to_buy_full_ownership?" => true },
]
end
def questions

5
app/models/form/sales/questions/deposit_amount.rb

@ -9,5 +9,10 @@ class Form::Sales::Questions::DepositAmount < ::Form::Question
@width = 5
@prefix = "£"
@hint_text = "Enter the total cash sum paid by the buyer towards the property that was not funded by the mortgage"
@derived = true
end
def selected_answer_option_is_derived?(_log)
true
end
end

18
app/models/form/sales/questions/extra_borrowing.rb

@ -0,0 +1,18 @@
class Form::Sales::Questions::ExtraBorrowing < ::Form::Question
def initialize(id, hsh, page)
super
@id = "extrabor"
@check_answer_label = "Any other borrowing?"
@header = "Does this include any extra borrowing?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@page = page
@hint_text = ""
end
ANSWER_OPTIONS = {
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
"3" => { "value" => "Don't know" },
}.freeze
end

58
app/models/form/sales/questions/mortgage_lender.rb

@ -0,0 +1,58 @@
class Form::Sales::Questions::MortgageLender < ::Form::Question
def initialize(id, hsh, page)
super
@id = "mortgagelender"
@check_answer_label = "Mortgage Lender"
@header = "What is the name of the mortgage lender?"
@type = "select"
@hint_text = ""
@page = page
@answer_options = ANSWER_OPTIONS
@guidance_position = GuidancePosition::BOTTOM
@guidance_partial = "mortgage_lender"
end
ANSWER_OPTIONS = {
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society",
"4" => "Buckinghamshire Building Society",
"5" => "Cambridge Building Society",
"6" => "Coventry Building Society",
"7" => "Cumberland Building Society",
"8" => "Darlington Building Society",
"9" => "Dudley Building Society",
"10" => "Ecology Building Society",
"11" => "Halifax",
"12" => "Hanley Economic Building Society",
"13" => "Hinckley and Rugby Building Society",
"14" => "Holmesdale Building Society",
"15" => "Ipswich Building Society",
"16" => "Leeds Building Society",
"17" => "Lloyds Bank",
"18" => "Mansfield Building Society",
"19" => "Market Harborough Building Society",
"20" => "Melton Mowbray Building Society",
"21" => "Nationwide Building Society",
"22" => "Natwest",
"23" => "Nedbank Private Wealth",
"24" => "Newbury Building Society",
"25" => "OneSavings Bank",
"26" => "Parity Trust",
"27" => "Penrith Building Society",
"28" => "Pepper Homeloans",
"29" => "Royal Bank of Scotland",
"30" => "Santander",
"31" => "Skipton Building Society",
"32" => "Teachers Building Society",
"33" => "The Co-operative Bank",
"34" => "Tipton & Coseley Building Society",
"35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
}.freeze
end

10
app/models/form/sales/questions/mortgage_lender_other.rb

@ -0,0 +1,10 @@
class Form::Sales::Questions::MortgageLenderOther < ::Form::Question
def initialize(id, hsh, page)
super
@id = "mortgagelenderother"
@check_answer_label = "Other Mortgage Lender"
@header = "What is the other mortgage lender?"
@type = "text"
@page = page
end
end

21
app/models/form/sales/questions/postcode.rb

@ -0,0 +1,21 @@
class Form::Sales::Questions::Postcode < ::Form::Question
def initialize(id, hsh, page)
super
@id = "postcode_full"
@check_answer_label = "Property’s postcode"
@header = "Postcode"
@type = "text"
@width = 5
@inferred_check_answers_value = {
"condition" => {
"pcodenk" => 1,
},
"value" => "Not known",
}
@inferred_answers = {
"la" => {
"is_la_inferred" => true,
},
}
end
end

28
app/models/form/sales/questions/postcode_known.rb

@ -0,0 +1,28 @@
class Form::Sales::Questions::PostcodeKnown < ::Form::Question
def initialize(id, hsh, page)
super
@id = "pcodenk"
@check_answer_label = "Property’s postcode"
@header = "Do you know the property’s postcode?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@conditional_for = {
"postcode_full" => [0],
}
@hidden_in_check_answers = {
"depends_on" => [
{
"pcodenk" => 0,
},
{
"pcodenk" => 1,
},
],
}
end
ANSWER_OPTIONS = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}.freeze
end

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

@ -11,9 +11,13 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_discounted_ownership", nil, self),
Form::Sales::Pages::AboutPriceRtb.new(nil, nil, self),
Form::Sales::Pages::AboutPriceNotRtb.new(nil, nil, self),
Form::Sales::Pages::PurchasePrice.new("purchase_price_discounted_ownership", nil, self),
Form::Sales::Pages::Mortgageused.new("mortgage_used_discounted_ownership", nil, self),
Form::Sales::Pages::MortgageAmount.new("mortgage_amount_discounted_ownership", nil, self),
Form::Sales::Pages::MortgageLender.new("mortgage_lender_discounted_ownership", nil, self),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_discounted_ownership", nil, self),
Form::Sales::Pages::MortgageLength.new("mortgage_length_discounted_ownership", nil, self),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_discounted_ownership", nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_discounted_ownership", nil, self),
Form::Sales::Pages::DepositValueCheck.new("discounted_ownership_deposit_value_check", nil, self),
Form::Sales::Pages::LeaseholdCharges.new("leasehold_charges_discounted_ownership", nil, self),

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

@ -8,10 +8,13 @@ class Form::Sales::Subsections::OutrightSale < ::Form::Subsection
def pages
@pages ||= [
Form::Sales::Pages::PurchasePrice.new(nil, nil, self),
Form::Sales::Pages::PurchasePrice.new("purchase_price_outright_sale", nil, self),
Form::Sales::Pages::Mortgageused.new("mortgage_used_outright_sale", nil, self),
Form::Sales::Pages::MortgageAmount.new("mortgage_amount_outright_sale", nil, self),
Form::Sales::Pages::MortgageLender.new("mortgage_lender_outright_sale", nil, self),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_outright_sale", nil, self),
Form::Sales::Pages::MortgageLength.new("mortgage_length_outright_sale", nil, self),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_outright_sale", nil, self),
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),

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

@ -11,6 +11,7 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection
Form::Sales::Pages::PropertyNumberOfBedrooms.new(nil, nil, self),
Form::Sales::Pages::PropertyUnitType.new(nil, 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),
Form::Sales::Pages::PropertyWheelchairAccessible.new(nil, nil, self),
]

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

@ -22,7 +22,10 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::AboutPriceSharedOwnership.new(nil, nil, self),
Form::Sales::Pages::Mortgageused.new("mortgage_used_shared_ownership", nil, self),
Form::Sales::Pages::MortgageAmount.new("mortgage_amount_shared_ownership", nil, self),
Form::Sales::Pages::MortgageLender.new("mortgage_lender_shared_ownership", nil, self),
Form::Sales::Pages::MortgageLenderOther.new("mortgage_lender_other_shared_ownership", nil, self),
Form::Sales::Pages::MortgageLength.new("mortgage_length_shared_ownership", nil, self),
Form::Sales::Pages::ExtraBorrowing.new("extra_borrowing_shared_ownership", nil, self),
Form::Sales::Pages::AboutDepositWithDiscount.new(nil, nil, self),
Form::Sales::Pages::AboutDepositWithoutDiscount.new("about_deposit_shared_ownership", nil, self),
Form::Sales::Pages::DepositValueCheck.new("shared_ownership_deposit_value_check", nil, self),

8
app/models/lettings_log.rb

@ -424,10 +424,6 @@ class LettingsLog < Log
scheme_owning_organisation&.name
end
def scheme_managing_organisation_name
scheme_managing_organisation&.name
end
delegate :postcode, :name, :units, :type_of_unit, :mobility_type, :startdate, prefix: "location", to: :location, allow_nil: true
delegate :location_admin_district, to: :location, allow_nil: true
@ -608,10 +604,6 @@ private
self[la_key] = inferred_la if inferred_la.present?
end
def reset_location_fields!
reset_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1)
end
def get_has_benefits
HAS_BENEFITS_OPTIONS.include?(hb) ? 1 : 0
end

4
app/models/log.rb

@ -105,6 +105,10 @@ private
string.present? ? string.upcase.gsub(/\s+/, "") : string
end
def reset_location_fields!
reset_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1)
end
def reset_previous_location_fields!
reset_location(is_previous_la_inferred, "prevloc", "is_previous_la_inferred", "ppostcode_full", previous_la_known)
end

4
app/models/organisation.rb

@ -92,4 +92,8 @@ class Organisation < ApplicationRecord
{ name: "Data protection agreement", value: data_protection_agreement_string, editable: false },
].compact
end
def has_managing_agents?
managing_agents.count.positive?
end
end

23
app/models/sales_log.rb

@ -21,7 +21,9 @@ class SalesLog < Log
validates_with SalesLogValidator
before_validation :set_derived_fields!
before_validation :reset_invalidated_dependent_fields!
before_validation :process_postcode_changes!, if: :postcode_full_changed?
before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed?
before_validation :reset_location_fields!, unless: :postcode_known?
before_validation :reset_previous_location_fields!, unless: :previous_postcode_known?
scope :filter_by_year, ->(year) { where(saledate: Time.zone.local(year.to_i, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) }
@ -119,6 +121,10 @@ class SalesLog < Log
[9, 14, 27].include?(type)
end
def rent_to_buy_full_ownership?
type == 29
end
def is_type_discount?
type == 18
end
@ -135,6 +141,18 @@ class SalesLog < Log
ppcodenk&.zero?
end
def postcode_known?
pcodenk&.zero?
end
def postcode_full=(postcode)
if postcode
super UKPostcode.parse(postcode).to_s
else
super nil
end
end
def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key)
return if postcode.blank?
@ -151,4 +169,9 @@ class SalesLog < Log
def mortgage_not_used?
mortgageused == 2
end
def process_postcode_changes!
self.postcode_full = upcase_and_remove_whitespace(postcode_full)
process_postcode(postcode_full, "pcodenk", "is_la_inferred", "la")
end
end

11
app/models/scheme.rb

@ -1,6 +1,5 @@
class Scheme < ApplicationRecord
belongs_to :owning_organisation, class_name: "Organisation"
belongs_to :managing_organisation, optional: true, class_name: "Organisation"
has_many :locations, dependent: :delete_all
has_many :lettings_logs, class_name: "LettingsLog", dependent: :delete_all
has_many :scheme_deactivation_periods, class_name: "SchemeDeactivationPeriod"
@ -127,12 +126,6 @@ class Scheme < ApplicationRecord
]
end
def check_support_services_provider_attributes
[
{ name: "Organisation providing support", value: managing_organisation&.name, id: "managing_organisation_id" },
]
end
def check_primary_client_attributes
[
{ name: "Primary client group", value: primary_client_group, id: "primary_client_group" },
@ -196,10 +189,6 @@ class Scheme < ApplicationRecord
Scheme.intended_stays.keys.excluding("Missing").map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize, description: hints[key.to_sym]) }
end
def arrangement_type_same?
arrangement_type.present? && ARRANGEMENT_TYPE[arrangement_type.to_sym] == "D"
end
def validate_confirmed
required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units has_other_client_group deactivation_date deactivation_date_type]

2
app/models/user.rb

@ -145,7 +145,7 @@ class User < ApplicationRecord
end
def logs_filters(specific_org: false)
if support? && !specific_org
if (support? && !specific_org) || organisation.has_managing_agents?
%w[status years user organisation]
else
%w[status years user]

8
app/models/validations/property_validations.rb

@ -50,14 +50,6 @@ module Validations::PropertyValidations
end
end
def validate_property_postcode(record)
postcode = record.postcode_full
if record.postcode_known? && (postcode.blank? || !postcode.match(POSTCODE_REGEXP))
error_message = I18n.t("validations.postcode")
record.errors.add :postcode_full, error_message
end
end
def validate_shared_housing_rooms(record)
if record.beds.present? && record.beds <= 0
record.errors.add :beds, I18n.t("validations.property.beds.non_positive")

8
app/models/validations/shared_validations.rb

@ -34,6 +34,14 @@ module Validations::SharedValidations
end
end
def validate_property_postcode(record)
postcode = record.postcode_full
if record.postcode_known? && (postcode.blank? || !postcode.match(POSTCODE_REGEXP))
error_message = I18n.t("validations.postcode")
record.errors.add :postcode_full, error_message
end
end
def location_during_startdate_validation(record, field)
location_inactive_status = inactive_status(record.startdate, record.location)

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

@ -154,7 +154,7 @@ class BulkUpload::Lettings::Validator
row_parsers.each_with_index do |row_parser, index|
row_parser.valid?
row = index + row_offset
row = index + row_offset + 1
row_parser.errors.each do |error|
bulk_upload.bulk_upload_errors.create!(
@ -163,7 +163,7 @@ class BulkUpload::Lettings::Validator
tenant_code: row_parser.field_7,
property_ref: row_parser.field_100,
row:,
cell: "#{cols[field_number_for_attribute(error.attribute) - col_offset + 1]}#{row + 1}",
cell: "#{cols[field_number_for_attribute(error.attribute) - col_offset + 1]}#{row}",
)
end
end

2
app/services/csv/lettings_log_csv_service.rb

@ -42,7 +42,7 @@ module Csv
metadata_fields = %w[id status created_at updated_at created_by_name is_dpo owning_organisation_name managing_organisation_name collection_start_year]
metadata_id_fields = %w[managing_organisation_id owning_organisation_id created_by_id]
scheme_and_location_ids = %w[scheme_id location_id]
scheme_attributes = %w[scheme_code scheme_service_name scheme_sensitive scheme_type scheme_registered_under_care_act scheme_owning_organisation_name scheme_managing_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at]
scheme_attributes = %w[scheme_code scheme_service_name scheme_sensitive scheme_type scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at]
location_attributes = %w[location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate]
intersecting_attributes = ordered_form_questions & LettingsLog.attribute_names - scheme_and_location_ids
remaining_attributes = LettingsLog.attribute_names - intersecting_attributes - scheme_and_location_ids

16
app/services/imports/scheme_import_service.rb

@ -9,7 +9,6 @@ module Imports
if attributes["status"] == "Approved"
Scheme.create!(
owning_organisation_id: attributes["owning_organisation_id"],
managing_organisation_id: attributes["managing_organisation_id"],
service_name: attributes["service_name"],
arrangement_type: attributes["arrangement_type"],
old_id: attributes["old_id"],
@ -49,12 +48,6 @@ module Imports
attributes["arrangement_type"] = string_or_nil(xml_doc, "arrangement_type")
attributes["owning_org_old_id"] = string_or_nil(xml_doc, "institution")
attributes["owning_organisation_id"] = find_owning_organisation_id(attributes["owning_org_old_id"])
attributes["management_org_old_visible_id"] = safe_string_as_integer(xml_doc, "agent")
attributes["managing_organisation_id"] = find_managing_organisation_id(attributes["management_org_old_visible_id"])
if attributes["arrangement_type"] == "D" && attributes["managing_organisation_id"].nil?
attributes["managing_organisation_id"] = attributes["owning_organisation_id"]
end
attributes
end
@ -65,14 +58,5 @@ module Imports
organisation.id
end
def find_managing_organisation_id(old_visible_id)
return unless old_visible_id
organisation = Organisation.find_by(old_visible_id:)
raise "Organisation not found with legacy visible ID #{old_visible_id}" if organisation.nil?
organisation.id
end
end
end

1
app/services/imports/scheme_location_import_service.rb

@ -38,7 +38,6 @@ module Imports
end_date: attributes["end_date"],
# These values were set by the scheme import (management groups)
owning_organisation_id: source_scheme.owning_organisation_id,
managing_organisation_id: source_scheme.managing_organisation_id,
service_name: source_scheme.service_name,
arrangement_type: source_scheme.arrangement_type,
old_id: source_scheme.old_id,

7
app/views/form/guidance/_mortgage_lender.html.erb

@ -0,0 +1,7 @@
<%= govuk_details(summary_text: "Can’t find the mortgage lender you’re looking for?") do %>
<ul class="govuk-list govuk-list--bullet">
<li>Double check the spelling and try again</li>
<li>Type the first few letters to see the suggestions</li>
<li>Type Other and continue - we’ll ask you to type in your answer in the next question</li>
</ul>
<% end %>

4
app/views/logs/_log_filters.erb

@ -10,7 +10,7 @@
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: years, label: "Collection year", category: "years" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: status_filters, label: "Status", category: "status" } %>
<%= render partial: "filters/radio_filter", locals: { f: f, options: all_or_yours, label: "Logs", category: "user", } %>
<% if @current_user.support? && request.path == "/lettings-logs" %>
<% if (@current_user.support? || @current_user.organisation.has_managing_agents?) && request.path == "/lettings-logs" %>
<%= render partial: "filters/radio_filter", locals: {
f: f,
options: {
@ -21,7 +21,7 @@
type: "select",
label: "Organisation",
category: "organisation",
options: [OpenStruct.new(id: "", name: "Select an option")] + Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) }
options: organisations_filter_options(@current_user)
}
}
},

5
app/views/schemes/check_answers.html.erb

@ -12,11 +12,6 @@
<% next if current_user.data_coordinator? && attr[:name] == ("owned by") %>
<%= render partial: "scheme_summary_list_row", locals: { scheme: @scheme, attribute: attr, change_link: @scheme.confirmed? ? scheme_edit_name_path(@scheme) : scheme_details_path(@scheme, check_answers: true) } %>
<% end %>
<% if !@scheme.arrangement_type_same? %>
<% @scheme.check_support_services_provider_attributes.each do |attr| %>
<%= render partial: "scheme_summary_list_row", locals: { scheme: @scheme, attribute: attr, change_link: scheme_support_services_provider_path(@scheme, check_answers: true) } %>
<% end %>
<% end %>
<% @scheme.check_primary_client_attributes.each do |attr| %>
<%= render partial: "scheme_summary_list_row", locals: { scheme: @scheme, attribute: attr, change_link: scheme_primary_client_group_path(@scheme, check_answers: true) } %>
<% end %>

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

@ -2,8 +2,6 @@
<% if request.referer&.include?("new") || request.referer&.include?("details") %>
<% back_button_path = scheme_details_path(@scheme) %>
<% elsif request.referer&.include?("provider") %>
<% back_button_path = scheme_support_services_provider_path(@scheme) %>
<% elsif request.query_parameters["check_answers"] %>
<% back_button_path = scheme_check_answers_path(@scheme) %>
<% end %>

34
app/views/schemes/support_services_provider.html.erb

@ -1,34 +0,0 @@
<% content_for :title, "Which organisation provides the support services used by this scheme?" %>
<% content_for :before_content do %>
<%= govuk_back_link(
text: "Back",
href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/details",
) %>
<% end %>
<%= form_for(@scheme, method: :patch) do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= f.govuk_error_summary %>
<% null_option = [OpenStruct.new(id: "", name: "Select an option")] %>
<% organisations = Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) } %>
<% managing_org_answer_options = null_option + organisations %>
<%= f.govuk_collection_select :managing_organisation_id,
managing_org_answer_options,
:id,
:name,
label: { text: "Which organisation provides the support services used by this scheme?", size: "m" },
options: { required: true },
"data-controller": %w[accessible-autocomplete conditional-filter] %>
<%= f.hidden_field :page, value: "support-services-provider" %>
<% if request.query_parameters["check_answers"] %>
<%= f.hidden_field :check_answers, value: "true" %>
<% end %>
<%= f.govuk_submit "Save and continue" %>
</div>
</div>
<% end %>

2
config/locales/en.yml

@ -71,8 +71,6 @@ en:
attributes:
owning_organisation_id:
invalid: "Enter the name of the organisation that owns the housing stock"
managing_organisation_id:
invalid: "Enter the name of the organisation that manages the housing stock"
service_name:
invalid: "Enter the name of the scheme"
scheme_type:

8
db/migrate/20230109144039_add_mortgage_lender.rb

@ -0,0 +1,8 @@
class AddMortgageLender < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :mortgagelender, :integer
t.column :mortgagelenderother, :string
end
end
end

7
db/migrate/20230109170748_add_extrabor_to_sales.rb

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

11
db/migrate/20230111134640_remove_managing_organisation_id_from_schemes.rb

@ -0,0 +1,11 @@
class RemoveManagingOrganisationIdFromSchemes < ActiveRecord::Migration[7.0]
def up
change_table :schemes, bulk: true do |t|
t.remove :managing_organisation_id
end
end
def down
add_reference :schemes, :managing_organisation_id, foreign_key: { to_table: :organisations }
end
end

10
db/migrate/20230113091706_add_derived_household_fields.rb

@ -0,0 +1,10 @@
class AddDerivedHouseholdFields < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :hhmemb, :integer
t.column :totadult, :integer
t.column :totchild, :integer
t.column :hhtype, :integer
end
end
end

11
db/migrate/20230113125117_add_postcode_fields_to_sales.rb

@ -0,0 +1,11 @@
class AddPostcodeFieldsToSales < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :pcode1, :string
t.column :pcode2, :string
t.column :pcodenk, :integer
t.column :postcode_full, :string
t.column :is_la_inferred, :boolean
end
end
end

29
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_12_093524) do
ActiveRecord::Schema[7.0].define(version: 2023_01_13_125117) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -434,6 +434,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_093524) do
t.string "relat5"
t.string "relat6"
t.integer "hb"
t.string "sex4"
t.string "sex5"
t.string "sex6"
t.integer "savings_value_check"
t.integer "deposit_value_check"
t.integer "frombeds"
@ -470,22 +473,31 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_093524) do
t.integer "hhregres"
t.integer "hhregresstill"
t.integer "proplen"
t.integer "mscharge_known"
t.decimal "mscharge", precision: 10, scale: 2
t.integer "prevten"
t.integer "mortgageused"
t.integer "wchair"
t.integer "armedforcesspouse"
t.integer "mscharge_known"
t.decimal "mscharge", precision: 10, scale: 2
t.string "sex4"
t.string "sex5"
t.string "sex6"
t.integer "mortlen"
t.datetime "hodate", precision: nil
t.integer "hoday"
t.integer "homonth"
t.integer "hoyear"
t.integer "fromprop"
t.integer "socprevten"
t.integer "mortgagelender"
t.string "mortgagelenderother"
t.integer "mortlen"
t.string "pcode1"
t.string "pcode2"
t.integer "pcodenk"
t.string "postcode_full"
t.boolean "is_la_inferred"
t.integer "extrabor"
t.integer "hhmemb"
t.integer "totadult"
t.integer "totchild"
t.integer "hhtype"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id"
@ -515,13 +527,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_093524) do
t.string "intended_stay"
t.datetime "end_date"
t.integer "has_other_client_group"
t.bigint "managing_organisation_id"
t.string "arrangement_type"
t.string "old_id"
t.string "old_visible_id"
t.integer "total_units"
t.boolean "confirmed"
t.index ["managing_organisation_id"], name: "index_schemes_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id"
end
@ -586,7 +596,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_12_093524) do
add_foreign_key "organisation_relationships", "organisations", column: "child_organisation_id"
add_foreign_key "organisation_relationships", "organisations", column: "parent_organisation_id"
add_foreign_key "sales_logs", "organisations", column: "owning_organisation_id", on_delete: :cascade
add_foreign_key "schemes", "organisations", column: "managing_organisation_id"
add_foreign_key "schemes", "organisations", column: "owning_organisation_id", on_delete: :cascade
add_foreign_key "users", "organisations", on_delete: :cascade
end

3
db/seeds.rb

@ -236,7 +236,6 @@ unless Rails.env.test?
primary_client_group: "O",
secondary_client_group: "H",
owning_organisation: org,
managing_organisation: org,
arrangement_type: "D",
confirmed: true,
created_at: Time.zone.now,
@ -252,7 +251,6 @@ unless Rails.env.test?
primary_client_group: "D",
secondary_client_group: "E",
owning_organisation: org,
managing_organisation: org,
arrangement_type: "D",
confirmed: true,
created_at: Time.zone.now,
@ -268,7 +266,6 @@ unless Rails.env.test?
primary_client_group: "G",
secondary_client_group: "R",
owning_organisation: dummy_org,
managing_organisation: dummy_org,
arrangement_type: "D",
confirmed: true,
created_at: Time.zone.now,

16
spec/components/bulk_upload_error_row_component_spec.rb

@ -49,6 +49,22 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
expect(result).to have_content(expected)
end
context "when multiple errors for a row" do
subject(:component) { described_class.new(bulk_upload_errors:) }
let(:bulk_upload_errors) do
[
build(:bulk_upload_error, cell: "Z1"),
build(:bulk_upload_error, cell: "AB1"),
build(:bulk_upload_error, cell: "A1"),
]
end
it "is sorted by cell" do
expect(component.bulk_upload_errors.map(&:cell)).to eql(%w[A1 Z1 AB1])
end
end
context "when a sales bulk upload" do
let(:bulk_upload) { create(:bulk_upload, :sales) }
let(:field) { :field_87 }

6
spec/factories/sales_log.rb

@ -57,7 +57,7 @@ FactoryBot.define do
income2nk { 0 }
income2 { 10_000 }
inc2mort { 1 }
la_known { "1" }
la_known { 1 }
la { "E09000003" }
savingsnk { 1 }
prevown { 1 }
@ -96,6 +96,10 @@ FactoryBot.define do
mscharge_known { 1 }
mscharge { 100 }
mortlen { 10 }
pcodenk { 1 }
is_la_inferred { false }
mortgagelender { 5 }
extrabor { 1 }
end
end
end

1
spec/factories/scheme.rb

@ -10,7 +10,6 @@ FactoryBot.define do
primary_client_group { %w[O H M L A G F B D E I S N R Q P X].sample }
secondary_client_group { %w[O H M L A G F B D E I S N R Q P X].sample }
owning_organisation { FactoryBot.create(:organisation) }
managing_organisation { FactoryBot.create(:organisation) }
confirmed { true }
created_at { Time.zone.local(2021, 4, 1) }
trait :export do

2
spec/features/form/accessible_autocomplete_spec.rb

@ -61,7 +61,7 @@ RSpec.describe "Accessible Automcomplete" do
end
context "when searching schemes" do
let(:scheme) { FactoryBot.create(:scheme, owning_organisation_id: lettings_log.created_by.organisation_id, managing_organisation_id: lettings_log.created_by.organisation_id, primary_client_group: "Q", secondary_client_group: "P") }
let(:scheme) { FactoryBot.create(:scheme, owning_organisation_id: lettings_log.created_by.organisation_id, primary_client_group: "Q", secondary_client_group: "P") }
before do
FactoryBot.create(:location, scheme:, postcode: "W6 0ST")

16
spec/features/schemes_helpers.rb

@ -38,11 +38,16 @@ module SchemesHelpers
click_button "Save and continue"
end
def fill_in_and_save_secondary_client_group_confirmation
def fill_in_and_save_secondary_client_group_confirmation_yes
choose "Yes"
click_button "Save and continue"
end
def fill_in_and_save_secondary_client_group_confirmation_no
choose "No"
click_button "Save and continue"
end
def fill_in_and_save_secondary_client_group
choose "Offenders and people at risk of offending"
click_button "Save and continue"
@ -97,8 +102,15 @@ module SchemesHelpers
def create_and_save_a_scheme
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
fill_in_and_save_secondary_client_group
fill_in_and_save_support
end
def create_and_save_a_scheme_no_secondary_client_group
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation_no
fill_in_and_save_support
end
end

60
spec/features/schemes_spec.rb

@ -423,14 +423,14 @@ RSpec.describe "Schemes scheme Features" do
it "allows selecting secondary client group if the scheme provides for it" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
expect(page).to have_content "What is the other client group?"
end
it "allows amending secondary client group confirmation question after navigating from secondary client group question" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
click_link "Back"
expect(page).to have_current_path("/schemes/#{scheme.id}/confirm-secondary-client-group")
expect(page).to have_content "Does this scheme provide for another client group?"
@ -439,7 +439,7 @@ RSpec.describe "Schemes scheme Features" do
it "returns to the secondary group details question after amending secondary group details confirmation" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
click_link "Back"
click_button "Save and continue"
expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group")
@ -448,7 +448,7 @@ RSpec.describe "Schemes scheme Features" do
it "allows selecting the level of support" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
fill_in_and_save_secondary_client_group
expect(page).to have_content "What support does this scheme provide?"
end
@ -456,7 +456,7 @@ RSpec.describe "Schemes scheme Features" do
it "allows amending secondary client group question after navigating from level of support" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
fill_in_and_save_secondary_client_group
click_link "Back"
expect(page).to have_current_path("/schemes/#{scheme.id}/secondary-client-group")
@ -466,7 +466,7 @@ RSpec.describe "Schemes scheme Features" do
it "returns to the level of support question after amending secondary group details" do
fill_in_and_save_scheme_details
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
fill_in_and_save_secondary_client_group
click_link "Back"
click_button "Save and continue"
@ -553,11 +553,11 @@ RSpec.describe "Schemes scheme Features" do
context "when changing scheme answers" do
before do
create_and_save_a_scheme
create_and_save_a_scheme_no_secondary_client_group
end
it "displays change links" do
assert_selector "a", text: "Change", count: 12
assert_selector "a", text: "Change", count: 11
end
it "allows changing details questions" do
@ -579,9 +579,10 @@ RSpec.describe "Schemes scheme Features" do
end
it "indicates if the scheme is not complete" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
choose "Another registered stock owner"
click_link("Change", href: "/schemes/#{scheme.id}/confirm-secondary-client-group?check_answers=true", match: :first)
choose "Yes"
click_button "Save and continue"
visit("/schemes/#{scheme.id}/check-answers")
expect(page).to have_content("You didn’t answer this question")
end
end
@ -604,50 +605,25 @@ RSpec.describe "Schemes scheme Features" do
context "when I fill in scheme details indicating that supported services provided by a different organisation and I press save I see primary client group section" do
let(:scheme) { Scheme.first }
let!(:another_organisation) { FactoryBot.create(:organisation, name: "Another Org") }
before do
fill_in_and_save_scheme_details({ "housing_stock_owners" => "Another registered stock owner" })
end
it "lets me fill in the managing organisation details" do
expect(page).to have_content "Which organisation provides the support services used by this scheme?"
end
it "lets me fill in the scheme details after navigating back" do
click_link "Back"
expect(page).to have_current_path("/schemes/#{scheme.id}/details")
expect(page).to have_content "Scheme name"
expect(page).to have_content "This scheme contains confidential information"
expect(page).to have_content "What is this type of scheme?"
expect(page).to have_content "Who provides the support services used by this scheme?"
expect(page).to have_content "Is this scheme registered under the Care Standards Act 2000?"
end
it "returns to the support service provider after amending the question" do
click_link "Back"
click_button "Save and continue"
expect(page).to have_current_path("/schemes/#{scheme.id}/support-services-provider")
end
it "lets the primary client group to be selected" do
select another_organisation.name, from: "scheme-managing-organisation-id-field"
click_button "Save and continue"
expect(page).to have_content "What client group is this scheme intended for?"
end
context "when changing scheme answers" do
before do
select another_organisation.name, from: "scheme-managing-organisation-id-field"
click_button "Save and continue"
fill_in_and_save_primary_client_group
fill_in_and_save_secondary_client_group_confirmation
fill_in_and_save_secondary_client_group_confirmation_yes
fill_in_and_save_secondary_client_group
fill_in_and_save_support
end
it "displays change links" do
assert_selector "a", text: "Change", count: 13
assert_selector "a", text: "Change", count: 12
end
it "allows changing details questions" do
@ -668,11 +644,11 @@ RSpec.describe "Schemes scheme Features" do
expect(page).to have_content "Check your changes before creating this scheme"
end
it "keeps the provider answer when swithing between other provider options" do
click_link("Change", href: "/schemes/#{scheme.id}/details?check_answers=true", match: :first)
choose "Another organisation"
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 and continue"
expect(page).to have_content(another_organisation.name)
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
@ -1039,7 +1015,7 @@ RSpec.describe "Schemes scheme Features" do
context "when selecting a scheme" do
let!(:user) { FactoryBot.create(:user, :data_coordinator, last_sign_in_at: Time.zone.now) }
let!(:schemes) { FactoryBot.create_list(:scheme, 5, owning_organisation: user.organisation, managing_organisation: user.organisation, arrangement_type: "The same organisation that owns the housing stock") }
let!(:schemes) { FactoryBot.create_list(:scheme, 5, owning_organisation: user.organisation, arrangement_type: "The same organisation that owns the housing stock") }
let(:location) { FactoryBot.create(:location, scheme: schemes[2]) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, created_by: user, needstype: 2) }

4
spec/fixtures/files/lettings_logs_download.csv vendored

@ -1,2 +1,2 @@
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_managing_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,needstype,renewal,startdate,rent_type_detail,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,hhmemb,relat2,age2,sex2,retirement_value_check,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,is_previous_la_inferred,prevloc_label,prevloc,illness_type_1,illness_type_2,is_la_inferred,la_label,la,postcode_known,postcode_full,previous_la_known,wchair,preg_occ,cbl,earnings,incfreq,net_income_value_check,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,first_time_property_let_as_social_housing,unitletas,builtype,voiddate,renttype,lettype,totchild,totelder,totadult,net_income_known,nocharge,is_carehome,household_charge,referral,tshortfall,chcharge,ppcodenk,age1_known,age2_known,age3_known,age4_known,age5_known,age6_known,age7_known,age8_known,ethnic_group,letting_allocation_unknown,details_known_2,details_known_3,details_known_4,details_known_5,details_known_6,details_known_7,details_known_8,has_benefits,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,rent_value_check,old_form_id,lar,irproduct,old_id,joint,tshortfall_known,sheltered,pregnancy_value_check,hhtype,new_old,vacdays,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unresolved,updated_by_id,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,Supported housing,,2 October 2021,London Affordable Rent,,,,,,,,,,,,,,,,,,,,No,,,,,No,Westminster,E09000033,,SE1 1TE,,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,8,0,0,0,,0,,,,,,,,,,,,,,,,,,,,,,,,0,,,,,,,0,,,,,,,,,,,,,,,,,,,9,1,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}

1 id status created_at updated_at created_by_name is_dpo owning_organisation_name managing_organisation_name collection_start_year needstype renewal startdate rent_type_detail irproduct_other tenancycode propcode age1 sex1 ecstat1 hhmemb relat2 age2 sex2 retirement_value_check ecstat2 armedforces leftreg illness housingneeds_a housingneeds_b housingneeds_c housingneeds_h is_previous_la_inferred prevloc_label prevloc illness_type_1 illness_type_2 is_la_inferred la_label la postcode_known postcode_full previous_la_known wchair preg_occ cbl earnings incfreq net_income_value_check benefits hb period brent scharge pscharge supcharg tcharge offered layear ppostcode_full mrcdate declaration ethnic national prevten age3 sex3 ecstat3 age4 sex4 ecstat4 age5 sex5 ecstat5 age6 sex6 ecstat6 age7 sex7 ecstat7 age8 sex8 ecstat8 homeless underoccupation_benefitcap reservist startertenancy tenancylength tenancy rsnvac unittype_gn beds waityear reasonpref chr cap reasonother housingneeds_f housingneeds_g illness_type_3 illness_type_4 illness_type_8 illness_type_5 illness_type_6 illness_type_7 illness_type_9 illness_type_10 rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow tenancyother property_owner_organisation property_manager_organisation purchaser_code reason majorrepairs hbrentshortfall property_relet incref first_time_property_let_as_social_housing unitletas builtype voiddate renttype lettype totchild totelder totadult net_income_known nocharge is_carehome household_charge referral tshortfall chcharge ppcodenk age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known ethnic_group letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 has_benefits wrent wscharge wpschrge wsupchrg wtcharge wtshortfall refused housingneeds wchchrg newprop relat3 relat4 relat5 relat6 relat7 relat8 rent_value_check old_form_id lar irproduct old_id joint tshortfall_known sheltered pregnancy_value_check hhtype new_old vacdays major_repairs_date_value_check void_date_value_check housingneeds_type housingneeds_other unresolved updated_by_id unittype_sh scheme_code scheme_service_name scheme_sensitive scheme_type scheme_registered_under_care_act scheme_owning_organisation_name scheme_managing_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 {id} in_progress 2022-02-08 16:52:15 +0000 2022-02-08 16:52:15 +0000 Danny Rojas No DLUHC DLUHC 2021 Supported housing 2 October 2021 London Affordable Rent No No Westminster E09000033 SE1 1TE No 2 8 0 0 0 0 0 0 9 1 6 {scheme_code} {scheme_service_name} {scheme_sensitive} Missing No DLUHC DLUHC {scheme_primary_client_group} {scheme_secondary_client_group} {scheme_support_type} {scheme_intended_stay} 2021-04-01 00:00:00 +0100 {location_code} SE1 1TE Downing Street 20 Bungalow Fitted with equipment and adaptations Westminster {location_startdate}

4
spec/fixtures/files/lettings_logs_download_non_support.csv vendored

@ -1,2 +1,2 @@
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_managing_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}
id,status,created_at,updated_at,created_by_name,is_dpo,owning_organisation_name,managing_organisation_name,collection_start_year,renewal,startdate,irproduct_other,tenancycode,propcode,age1,sex1,ecstat1,relat2,age2,sex2,ecstat2,armedforces,leftreg,illness,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_h,prevloc_label,illness_type_1,illness_type_2,la_label,postcode_full,wchair,preg_occ,cbl,earnings,incfreq,benefits,hb,period,brent,scharge,pscharge,supcharg,tcharge,offered,layear,ppostcode_full,mrcdate,declaration,ethnic,national,prevten,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,reservist,startertenancy,tenancylength,tenancy,rsnvac,unittype_gn,beds,waityear,reasonpref,chr,cap,reasonother,housingneeds_f,housingneeds_g,illness_type_3,illness_type_4,illness_type_8,illness_type_5,illness_type_6,illness_type_7,illness_type_9,illness_type_10,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,tenancyother,property_owner_organisation,property_manager_organisation,purchaser_code,reason,majorrepairs,hbrentshortfall,property_relet,incref,unitletas,builtype,voiddate,lettype,nocharge,household_charge,referral,tshortfall,chcharge,ppcodenk,ethnic_group,has_benefits,refused,housingneeds,wchchrg,newprop,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,major_repairs_date_value_check,void_date_value_check,housingneeds_type,housingneeds_other,unittype_sh,scheme_code,scheme_service_name,scheme_sensitive,scheme_type,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
{id},in_progress,2022-02-08 16:52:15 +0000,2022-02-08 16:52:15 +0000,Danny Rojas,No,DLUHC,DLUHC,2021,,2 October 2021,,,,,,,,,,,,,,,,,,,,,Westminster,SE1 1TE,No,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,0,,,,,,,0,0,,,,,,,,,,,,,,,,,,6,{scheme_code},{scheme_service_name},{scheme_sensitive},Missing,No,DLUHC,{scheme_primary_client_group},,{scheme_secondary_client_group},{scheme_support_type},{scheme_intended_stay},2021-04-01 00:00:00 +0100,{location_code},SE1 1TE,Downing Street,20,Bungalow,Fitted with equipment and adaptations,Westminster,{location_startdate}

1 id status created_at updated_at created_by_name is_dpo owning_organisation_name managing_organisation_name collection_start_year renewal startdate irproduct_other tenancycode propcode age1 sex1 ecstat1 relat2 age2 sex2 ecstat2 armedforces leftreg illness housingneeds_a housingneeds_b housingneeds_c housingneeds_h prevloc_label illness_type_1 illness_type_2 la_label postcode_full wchair preg_occ cbl earnings incfreq benefits hb period brent scharge pscharge supcharg tcharge offered layear ppostcode_full mrcdate declaration ethnic national prevten age3 sex3 ecstat3 age4 sex4 ecstat4 age5 sex5 ecstat5 age6 sex6 ecstat6 age7 sex7 ecstat7 age8 sex8 ecstat8 homeless underoccupation_benefitcap reservist startertenancy tenancylength tenancy rsnvac unittype_gn beds waityear reasonpref chr cap reasonother housingneeds_f housingneeds_g illness_type_3 illness_type_4 illness_type_8 illness_type_5 illness_type_6 illness_type_7 illness_type_9 illness_type_10 rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow tenancyother property_owner_organisation property_manager_organisation purchaser_code reason majorrepairs hbrentshortfall property_relet incref unitletas builtype voiddate lettype nocharge household_charge referral tshortfall chcharge ppcodenk ethnic_group has_benefits refused housingneeds wchchrg newprop relat3 relat4 relat5 relat6 relat7 relat8 lar irproduct joint sheltered major_repairs_date_value_check void_date_value_check housingneeds_type housingneeds_other unittype_sh scheme_code scheme_service_name scheme_sensitive scheme_type scheme_registered_under_care_act scheme_owning_organisation_name scheme_managing_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 {id} in_progress 2022-02-08 16:52:15 +0000 2022-02-08 16:52:15 +0000 Danny Rojas No DLUHC DLUHC 2021 2 October 2021 Westminster SE1 1TE No 8 0 0 0 6 {scheme_code} {scheme_service_name} {scheme_sensitive} Missing No DLUHC DLUHC {scheme_primary_client_group} {scheme_secondary_client_group} {scheme_support_type} {scheme_intended_stay} 2021-04-01 00:00:00 +0100 {location_code} SE1 1TE Downing Street 20 Bungalow Fitted with equipment and adaptations Westminster {location_startdate}

35
spec/helpers/filters_helper_spec.rb

@ -81,4 +81,39 @@ RSpec.describe FiltersHelper do
end
end
end
describe "#organisations_filter_options" do
let(:parent_organisation) { FactoryBot.create(:organisation, name: "Parent organisation") }
let(:child_organisation) { FactoryBot.create(:organisation, name: "Child organisation") }
before do
FactoryBot.create(:organisation_relationship, parent_organisation:, child_organisation:)
FactoryBot.create(:organisation, name: "Other organisation", id: 99)
end
context "with a support user" do
let(:user) { FactoryBot.create(:user, :support, organisation: parent_organisation) }
it "returns a list of all organisations" do
expect(organisations_filter_options(user)).to eq([
OpenStruct.new(id: "", name: "Select an option"),
OpenStruct.new(id: parent_organisation.id, name: "Parent organisation"),
OpenStruct.new(id: child_organisation.id, name: "Child organisation"),
OpenStruct.new(id: 99, name: "Other organisation"),
])
end
end
context "with a data coordinator user" do
let(:user) { FactoryBot.create(:user, :data_coordinator, organisation: parent_organisation) }
it "returns a list of managing agents and your own organisation" do
expect(organisations_filter_options(user)).to eq([
OpenStruct.new(id: "", name: "Select an option"),
OpenStruct.new(id: parent_organisation.id, name: "Parent organisation"),
OpenStruct.new(id: child_organisation.id, name: "Child organisation"),
])
end
end
end
end

3
spec/helpers/schemes_helper_spec.rb

@ -98,7 +98,6 @@ RSpec.describe SchemesHelper do
scheme_type: 7,
registered_under_care_act: 3,
owning_organisation:,
managing_organisation:,
arrangement_type: "V",
primary_client_group: "S",
has_other_client_group: 1,
@ -120,7 +119,6 @@ RSpec.describe SchemesHelper do
{ name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
{ name: "Housing stock owned by", value: "Acme LTD Owning", edit: true },
{ name: "Support services provided by", value: "A registered charity or voluntary organisation" },
{ name: "Organisation providing support", value: "Acme LTD Managing" },
{ name: "Primary client group", value: "Rough sleepers" },
{ name: "Has another client group", value: "Yes" },
{ name: "Secondary client group", value: "Refugees (permanent)" },
@ -140,7 +138,6 @@ RSpec.describe SchemesHelper do
{ name: "Type of scheme", value: "Housing for older people" },
{ name: "Registered under Care Standards Act 2000", value: "Yes – registered care home providing personal care" },
{ name: "Support services provided by", value: "A registered charity or voluntary organisation" },
{ name: "Organisation providing support", value: "Acme LTD Managing" },
{ name: "Primary client group", value: "Rough sleepers" },
{ name: "Has another client group", value: "Yes" },
{ name: "Secondary client group", value: "Refugees (permanent)" },

2
spec/models/form/lettings/questions/renewal_spec.rb

@ -28,7 +28,7 @@ RSpec.describe Form::Lettings::Questions::Renewal, type: :model do
end
it "has the correct hint_text" do
expect(question.hint_text).to be_nil
expect(question.hint_text).to eq("A renewal is a letting to the same tenant in the same property")
end
it "has the correct answer_options" do

2
spec/models/form/lettings/questions/scheme_id_spec.rb

@ -43,7 +43,7 @@ RSpec.describe Form::Lettings::Questions::SchemeId, type: :model do
let(:organisation) { FactoryBot.create(:organisation) }
let(:organisation_2) { FactoryBot.create(:organisation) }
let(:user) { FactoryBot.create(:user, organisation:) }
let(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation, managing_organisation: organisation) }
let(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation) }
let(:lettings_log) { FactoryBot.create(:lettings_log, created_by: user, needstype: 2) }
before do

4
spec/models/form/sales/pages/about_deposit_without_discount_spec.rb

@ -29,7 +29,9 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do
it "has correct depends_on" do
expect(page.depends_on).to eq(
[{ "is_type_discount?" => false }],
[{ "is_type_discount?" => false, "ownershipsch" => 1 },
{ "ownershipsch" => 2 },
{ "ownershipsch" => 3, "mortgageused" => 1 }],
)
end
end

1
spec/models/form/sales/pages/about_price_not_rtb_spec.rb

@ -30,6 +30,7 @@ RSpec.describe Form::Sales::Pages::AboutPriceNotRtb, type: :model do
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"right_to_buy?" => false,
"rent_to_buy_full_ownership?" => false,
}])
end
end

35
spec/models/form/sales/pages/extra_borrowing_spec.rb

@ -0,0 +1,35 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::ExtraBorrowing, 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) }
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[extrabor])
end
it "has the correct id" do
expect(page.id).to eq(nil)
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has the correct description" do
expect(page.description).to eq("")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"mortgageused" => 1,
}])
end
end

35
spec/models/form/sales/pages/mortgage_lender_other_spec.rb

@ -0,0 +1,35 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::MortgageLenderOther, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "mortgage_lender_other" }
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[mortgagelenderother])
end
it "has the correct id" do
expect(page.id).to eq("mortgage_lender_other")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has the correct description" do
expect(page.description).to eq("")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"mortgagelender" => 40,
}])
end
end

35
spec/models/form/sales/pages/mortgage_lender_spec.rb

@ -0,0 +1,35 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::MortgageLender, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "mortgage_lender" }
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[mortgagelender])
end
it "has the correct id" do
expect(page.id).to eq("mortgage_lender")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has the correct description" do
expect(page.description).to eq("")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{
"mortgageused" => 1,
}])
end
end

4
spec/models/form/sales/pages/mortgage_length_spec.rb

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

33
spec/models/form/sales/pages/postcode_spec.rb

@ -0,0 +1,33 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Postcode, 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) }
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[pcodenk postcode_full])
end
it "has the correct id" do
expect(page.id).to eq("property_postcode")
end
it "has the correct header" do
expect(page.header).to be_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

6
spec/models/form/sales/pages/property_local_authority_spec.rb

@ -31,4 +31,10 @@ RSpec.describe Form::Sales::Pages::PropertyLocalAuthority, type: :model do
it "has the correct description" do
expect(page.description).to be_nil
end
it "has the correct depends_on" do
expect(page.depends_on).to eq([{
"is_la_inferred" => false,
}])
end
end

7
spec/models/form/sales/pages/purchase_price_spec.rb

@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe Form::Sales::Pages::PurchasePrice, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_id) { "purchase_price" }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
@ -28,6 +28,9 @@ RSpec.describe Form::Sales::Pages::PurchasePrice, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to be_nil
expect(page.depends_on).to eq([
{ "ownershipsch" => 3 },
{ "rent_to_buy_full_ownership?" => true },
])
end
end

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

@ -27,8 +27,8 @@ RSpec.describe Form::Sales::Questions::DepositAmount, type: :model do
expect(question.type).to eq("numeric")
end
it "is not marked as derived" do
expect(question.derived?).to be false
it "is marked as derived" do
expect(question.derived?).to be true
end
it "has the correct hint" do

49
spec/models/form/sales/questions/extra_borrowing_spec.rb

@ -0,0 +1,49 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::ExtraBorrowing, 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) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("extrabor")
end
it "has the correct header" do
expect(question.header).to eq("Does this include any extra borrowing?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Any other borrowing?")
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
"3" => { "value" => "Don't know" },
})
end
it "has correct conditional for" do
expect(question.conditional_for).to eq(nil)
end
it "has the correct hint" do
expect(question.hint_text).to eq("")
end
end

37
spec/models/form/sales/questions/mortgage_lender_other_spec.rb

@ -0,0 +1,37 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::MortgageLenderOther, 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) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("mortgagelenderother")
end
it "has the correct header" do
expect(question.header).to eq("What is the other mortgage lender?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Other Mortgage Lender")
end
it "has the correct type" do
expect(question.type).to eq("text")
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
end

88
spec/models/form/sales/questions/mortgage_lender_spec.rb

@ -0,0 +1,88 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::MortgageLender, 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) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("mortgagelender")
end
it "has the correct header" do
expect(question.header).to eq("What is the name of the mortgage lender?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Mortgage Lender")
end
it "has the correct type" do
expect(question.type).to eq("select")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "is has correct guidance_position" do
expect(question.top_guidance?).to be false
expect(question.bottom_guidance?).to be true
end
it "is has correct guidance_partial" do
expect(question.guidance_partial).to eq("mortgage_lender")
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"" => "Select an option",
"1" => "Atom Bank",
"2" => "Barclays Bank PLC",
"3" => "Bath Building Society",
"4" => "Buckinghamshire Building Society",
"5" => "Cambridge Building Society",
"6" => "Coventry Building Society",
"7" => "Cumberland Building Society",
"8" => "Darlington Building Society",
"9" => "Dudley Building Society",
"10" => "Ecology Building Society",
"11" => "Halifax",
"12" => "Hanley Economic Building Society",
"13" => "Hinckley and Rugby Building Society",
"14" => "Holmesdale Building Society",
"15" => "Ipswich Building Society",
"16" => "Leeds Building Society",
"17" => "Lloyds Bank",
"18" => "Mansfield Building Society",
"19" => "Market Harborough Building Society",
"20" => "Melton Mowbray Building Society",
"21" => "Nationwide Building Society",
"22" => "Natwest",
"23" => "Nedbank Private Wealth",
"24" => "Newbury Building Society",
"25" => "OneSavings Bank",
"26" => "Parity Trust",
"27" => "Penrith Building Society",
"28" => "Pepper Homeloans",
"29" => "Royal Bank of Scotland",
"30" => "Santander",
"31" => "Skipton Building Society",
"32" => "Teachers Building Society",
"33" => "The Co-operative Bank",
"34" => "Tipton & Coseley Building Society",
"35" => "TSB",
"36" => "Ulster Bank",
"37" => "Virgin Money",
"38" => "West Bromwich Building Society",
"39" => "Yorkshire Building Society",
"40" => "Other",
})
end
end

59
spec/models/form/sales/questions/postcode_known_spec.rb

@ -0,0 +1,59 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::PostcodeKnown, 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) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("pcodenk")
end
it "has the correct header" do
expect(question.header).to eq("Do you know the property’s postcode?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Property’s postcode")
end
it "has the correct type" do
expect(question.type).to eq("radio")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
})
end
it "has correct conditional for" do
expect(question.conditional_for).to eq({
"postcode_full" => [0],
})
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [
{ "pcodenk" => 0 },
{ "pcodenk" => 1 },
],
})
end
end

58
spec/models/form/sales/questions/postcode_spec.rb

@ -0,0 +1,58 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::Postcode, 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) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("postcode_full")
end
it "has the correct header" do
expect(question.header).to eq("Postcode")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Property’s postcode")
end
it "has the correct type" do
expect(question.type).to eq("text")
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 width" do
expect(question.width).to eq(5)
end
it "has the correct inferred_answers" do
expect(question.inferred_answers).to eq({
"la" => {
"is_la_inferred" => true,
},
})
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq({
"condition" => {
"pcodenk" => 1,
},
"value" => "Not known",
})
end
end

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

@ -17,9 +17,13 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model
living_before_purchase_discounted_ownership
about_price_rtb
about_price_not_rtb
purchase_price_discounted_ownership
mortgage_used_discounted_ownership
mortgage_amount_discounted_ownership
mortgage_lender_discounted_ownership
mortgage_lender_other_discounted_ownership
mortgage_length_discounted_ownership
extra_borrowing_discounted_ownership
about_deposit_discounted_ownership
discounted_ownership_deposit_value_check
leasehold_charges_discounted_ownership

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

@ -14,10 +14,13 @@ RSpec.describe Form::Sales::Subsections::OutrightSale, type: :model do
it "has correct pages" do
expect(outright_sale.pages.map(&:id)).to eq(
%w[
purchase_price
purchase_price_outright_sale
mortgage_used_outright_sale
mortgage_amount_outright_sale
mortgage_lender_outright_sale
mortgage_lender_other_outright_sale
mortgage_length_outright_sale
extra_borrowing_outright_sale
about_deposit_outright_sale
outright_sale_deposit_value_check
leasehold_charges_outright_sale

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

@ -17,6 +17,7 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do
property_number_of_bedrooms
property_unit_type
property_building_type
property_postcode
property_local_authority
property_wheelchair_accessible
],

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

@ -28,7 +28,10 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
about_price_shared_ownership
mortgage_used_shared_ownership
mortgage_amount_shared_ownership
mortgage_lender_shared_ownership
mortgage_lender_other_shared_ownership
mortgage_length_shared_ownership
extra_borrowing_shared_ownership
about_deposit_with_discount
about_deposit_shared_ownership
shared_ownership_deposit_value_check

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(137)
expect(form.pages.count).to eq(148)
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(137)
expect(form.pages.count).to eq(148)
expect(form.name).to eq("2021_2022_sales")
end
end

6
spec/models/organisation_spec.rb

@ -4,7 +4,7 @@ RSpec.describe Organisation, type: :model do
describe "#new" do
let(:user) { FactoryBot.create(:user) }
let!(:organisation) { user.organisation }
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation, managing_organisation: organisation) }
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation) }
it "has expected fields" do
expect(organisation.attribute_names).to include("name", "phone", "provider_type")
@ -14,10 +14,6 @@ RSpec.describe Organisation, type: :model do
expect(organisation.users.first).to eq(user)
end
it "has managed_schemes" do
expect(organisation.managed_schemes.first).to eq(scheme)
end
it "has owned_schemes" do
expect(organisation.owned_schemes.first).to eq(scheme)
end

141
spec/models/sales_log_spec.rb

@ -127,6 +127,147 @@ RSpec.describe SalesLog, type: :model do
record_from_db = ActiveRecord::Base.connection.execute("select deposit from sales_logs where id=#{sales_log.id}").to_a[0]
expect(record_from_db["deposit"]).to eq(nil)
end
it "correctly derives and saves pcode1 and pcode1 and pcode2" do
sales_log.update!(postcode_full: "W6 0SP")
record_from_db = ActiveRecord::Base.connection.execute("select pcode1, pcode2 from sales_logs where id=#{sales_log.id}").to_a[0]
expect(record_from_db["pcode1"]).to eq("W6")
expect(record_from_db["pcode2"]).to eq("0SP")
end
end
context "when saving addresses" do
before do
stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\",\"codes\":{\"admin_district\": \"E08000003\"}}}", headers: {})
end
def check_postcode_fields(postcode_field)
record_from_db = ActiveRecord::Base.connection.execute("select #{postcode_field} from sales_logs where id=#{address_sales_log.id}").to_a[0]
expect(address_sales_log[postcode_field]).to eq("M1 1AE")
expect(record_from_db[postcode_field]).to eq("M1 1AE")
end
let!(:address_sales_log) do
FactoryBot.create(
:sales_log,
:completed,
managing_organisation: owning_organisation,
owning_organisation:,
created_by: created_by_user,
pcodenk: 0,
postcode_full: "M1 1AE",
)
end
def check_property_postcode_fields
check_postcode_fields("postcode_full")
end
it "correctly formats previous postcode" do
address_sales_log.update!(postcode_full: "M1 1AE")
check_property_postcode_fields
address_sales_log.update!(postcode_full: "m1 1ae")
check_property_postcode_fields
address_sales_log.update!(postcode_full: "m11Ae")
check_property_postcode_fields
address_sales_log.update!(postcode_full: "m11ae")
check_property_postcode_fields
end
it "correctly infers la" do
record_from_db = ActiveRecord::Base.connection.execute("select la from sales_logs where id=#{address_sales_log.id}").to_a[0]
expect(address_sales_log.la).to eq("E08000003")
expect(record_from_db["la"]).to eq("E08000003")
end
it "errors if the property postcode is emptied" do
expect { address_sales_log.update!({ postcode_full: "" }) }
.to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/)
end
it "errors if the property postcode is not valid" do
expect { address_sales_log.update!({ postcode_full: "invalid_postcode" }) }
.to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t("validations.postcode")}/)
end
context "when the local authority lookup times out" do
before do
allow(Timeout).to receive(:timeout).and_raise(Timeout::Error)
end
it "logs a warning" do
expect(Rails.logger).to receive(:warn).with("Postcodes.io lookup timed out")
address_sales_log.update!({ pcodenk: 1, postcode_full: "M1 1AD" })
end
end
it "correctly resets all fields if property postcode not known" do
address_sales_log.update!({ pcodenk: 1 })
record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0]
expect(record_from_db["postcode_full"]).to eq(nil)
expect(address_sales_log.la).to eq(nil)
expect(record_from_db["la"]).to eq(nil)
end
it "changes the LA if property postcode changes from not known to known and provided" do
address_sales_log.update!({ pcodenk: 1 })
address_sales_log.update!({ la: "E09000033" })
record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0]
expect(record_from_db["postcode_full"]).to eq(nil)
expect(address_sales_log.la).to eq("E09000033")
expect(record_from_db["la"]).to eq("E09000033")
address_sales_log.update!({ pcodenk: 0, postcode_full: "M1 1AD" })
record_from_db = ActiveRecord::Base.connection.execute("select la, postcode_full from sales_logs where id=#{address_sales_log.id}").to_a[0]
expect(record_from_db["postcode_full"]).to eq("M1 1AD")
expect(address_sales_log.la).to eq("E08000003")
expect(record_from_db["la"]).to eq("E08000003")
end
end
context "when deriving household variables" do
let!(:household_lettings_log) do
described_class.create!({
jointpur: 1,
hholdcount: 3,
relat2: "C",
relat3: "C",
relat4: "X",
relat5: "X",
age1: 22,
age2: 40,
age3: 19,
age4: 88,
age5: 14,
})
end
it "correctly derives and saves hhmemb" do
record_from_db = ActiveRecord::Base.connection.execute("select hhmemb from sales_logs where id=#{household_lettings_log.id}").to_a[0]
expect(record_from_db["hhmemb"]).to eq(5)
end
it "correctly derives and saves totchild" do
record_from_db = ActiveRecord::Base.connection.execute("select totchild from sales_logs where id=#{household_lettings_log.id}").to_a[0]
expect(record_from_db["totchild"]).to eq(2)
end
it "correctly derives and saves totadult" do
record_from_db = ActiveRecord::Base.connection.execute("select totadult from sales_logs where id=#{household_lettings_log.id}").to_a[0]
expect(record_from_db["totadult"]).to eq(3)
end
it "correctly derives and saves hhtype" do
record_from_db = ActiveRecord::Base.connection.execute("select hhtype from sales_logs where id=#{household_lettings_log.id}").to_a[0]
expect(record_from_db["hhtype"]).to eq(9)
end
end
context "when saving previous address" do

20
spec/models/user_spec.rb

@ -117,8 +117,24 @@ RSpec.describe User, type: :model do
})
end
it "can filter lettings logs by user, year and status" do
expect(user.logs_filters).to eq(%w[status years user])
context "and their organisation does not have managing agents" do
before do
user.organisation.update(holds_own_stock: false)
end
it "can filter lettings logs by user, year and status" do
expect(user.logs_filters).to eq(%w[status years user])
end
end
context "and their organisation has managing agents" do
before do
FactoryBot.create(:organisation_relationship, parent_organisation: user.organisation)
end
it "can filter lettings logs by user, year, status and organisation" do
expect(user.logs_filters).to eq(%w[status years user organisation])
end
end
end

2
spec/requests/form_controller_spec.rb

@ -250,7 +250,7 @@ RSpec.describe FormController, type: :request do
before do
locations = create_list(:location, 5)
locations.each { |location| location.scheme.update!(arrangement_type: "The same organisation that owns the housing stock", managing_organisation_id: location.scheme.owning_organisation_id) }
locations.each { |location| location.scheme.update!(arrangement_type: "The same organisation that owns the housing stock") }
end
it "returns an unfiltered list of schemes" do

43
spec/requests/schemes_controller_spec.rb

@ -451,7 +451,7 @@ RSpec.describe SchemesController, type: :request do
expect { post "/schemes", params: }.to change(Scheme, :count).by(1)
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("Which organisation provides the support services used by this scheme?")
expect(page).to have_content(" What client group is this scheme intended for?")
end
it "creates a new scheme for user organisation with valid params" do
@ -557,7 +557,7 @@ RSpec.describe SchemesController, type: :request do
expect { post "/schemes", params: }.to change(Scheme, :count).by(1)
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("Which organisation provides the support services used by this scheme?")
expect(page).to have_content("What client group is this scheme intended for?")
end
it "creates a new scheme for user organisation with valid params" do
@ -582,6 +582,7 @@ RSpec.describe SchemesController, type: :request do
{ scheme: { service_name: "",
scheme_type: "",
registered_under_care_act: "",
owning_organisation_id: nil,
arrangement_type: "" } }
end
@ -642,11 +643,11 @@ RSpec.describe SchemesController, type: :request do
end
context "when confirming unfinished scheme" do
let(:params) { { scheme: { owning_organisation_id: user.organisation.id, arrangement_type: "V", confirmed: true, page: "check-answers" } } }
let(:params) { { scheme: { owning_organisation_id: user.organisation.id, arrangement_type: nil, confirmed: true, page: "check-answers" } } }
it "does not allow the scheme to be confirmed" do
expect(response).to have_http_status(:unprocessable_entity)
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.managing_organisation_id.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.arrangement_type.invalid"))
end
end
@ -654,7 +655,6 @@ RSpec.describe SchemesController, type: :request do
let(:params) do
{ scheme: {
service_name: "",
managing_organisation_id: "",
primary_client_group: "",
secondary_client_group: "",
scheme_type: "",
@ -696,36 +696,6 @@ RSpec.describe SchemesController, type: :request do
end
end
context "when updating support services provider" do
let(:params) { { scheme: { arrangement_type: "Another organisation", managing_organisation_id: organisation.id, page: "support-services-provider" } } }
it "renders primary client group after successful update" do
follow_redirect!
expect(response).to have_http_status(:ok)
expect(page).to have_content("What client group is this scheme intended for?")
end
it "updates a scheme with valid params" do
follow_redirect!
expect(scheme_to_update.reload.managing_organisation_id).to eq(organisation.id)
end
context "when updating from check answers page" do
let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group", 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.primary_client_group).to eq("Homeless families with support needs")
end
end
end
context "when updating primary client group" do
let(:params) { { scheme: { primary_client_group: "Homeless families with support needs", page: "primary-client-group" } } }
@ -871,7 +841,6 @@ RSpec.describe SchemesController, type: :request do
registered_under_care_act: "No",
page: "details",
owning_organisation_id: organisation.id,
managing_organisation_id: organisation.id,
arrangement_type: "D" } }
end
@ -1171,7 +1140,6 @@ RSpec.describe SchemesController, type: :request do
expect(scheme_to_update.reload.sensitive).to eq("Yes")
expect(scheme_to_update.reload.registered_under_care_act).to eq("No")
expect(scheme_to_update.reload.owning_organisation_id).to eq(another_organisation.id)
expect(scheme_to_update.reload.managing_organisation_id).to eq(another_organisation.id)
end
context "when updating from check answers page" do
@ -1189,7 +1157,6 @@ RSpec.describe SchemesController, type: :request do
expect(scheme_to_update.reload.scheme_type).to eq("Foyer")
expect(scheme_to_update.reload.sensitive).to eq("Yes")
expect(scheme_to_update.reload.registered_under_care_act).to eq("No")
expect(scheme_to_update.reload.managing_organisation_id).to eq(scheme_to_update.owning_organisation_id)
end
end
end

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

@ -32,8 +32,15 @@ RSpec.describe BulkUpload::Lettings::Validator do
context "when a valid csv" do
let(:path) { file_fixture("2022_23_lettings_bulk_upload.csv") }
it do
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
end
it "create validation error with correct values" do
validator.call
error = BulkUploadError.first
expect(error.row).to eq("6")
end
end
end

1
spec/services/csv/lettings_log_csv_service_spec.rb

@ -208,7 +208,6 @@ RSpec.describe Csv::LettingsLogCsvService do
scheme_type
scheme_registered_under_care_act
scheme_owning_organisation_name
scheme_managing_organisation_name
scheme_primary_client_group
scheme_has_other_client_group
scheme_secondary_client_group

5
spec/services/imports/scheme_import_service_spec.rb

@ -10,7 +10,6 @@ RSpec.describe Imports::SchemeImportService do
let(:scheme_id) { "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d" }
let!(:owning_org) { FactoryBot.create(:organisation, old_org_id: "7c5bd5fb549c09z2c55d9cb90d7ba84927e64618") }
let!(:managing_org) { FactoryBot.create(:organisation, old_visible_id: "456") }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
@ -44,7 +43,6 @@ RSpec.describe Imports::SchemeImportService do
it "matches expected values" do
scheme = scheme_service.create_scheme(scheme_xml)
expect(scheme.owning_organisation).to eq(owning_org)
expect(scheme.managing_organisation).to eq(managing_org)
expect(scheme.old_id).to eq("6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d")
expect(scheme.old_visible_id).to eq("0123")
expect(scheme.service_name).to eq("Management Group")
@ -67,10 +65,9 @@ RSpec.describe Imports::SchemeImportService do
scheme_xml.at_xpath("//mgmtgroup:agent").content = ""
end
it "assigns both owning and managing organisation to the same one" do
it "assigns owning organisation" do
scheme = scheme_service.create_scheme(scheme_xml)
expect(scheme.owning_organisation).to eq(owning_org)
expect(scheme.managing_organisation).to eq(owning_org)
end
end
end

Loading…
Cancel
Save