Browse Source

Cldc 809 supported housing questions (#713)

* infer case_log values from schemes

* only display relevant property information questions

* Add unittype_sh column

* Display the correct number of completed sections

* fix schema and migration

* Fix test failing in CI

This test was failing due to some different between UTC and BST time as the
record from the DB comes back with a UTC timezone. Comparing the integer values
of both will ensure that both timestamps are identical and should fix the
issue in the CI where it thinks the values are different

* only run query for scheme locations size once

Co-authored-by: Dushan <dushan@madetech.com>

* extract TYPE_OF_UNIT_MAP

* lint

* Use find insted of select

Co-authored-by: Dushan Despotovic <dushan@madetech.com>
pull/724/head
kosiakkatrina 2 years ago committed by GitHub
parent
commit
8bd39704f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/helpers/tasklist_helper.rb
  2. 28
      app/models/derived_variables/case_log_variables.rb
  3. 2
      app/models/form/subsection.rb
  4. 16
      app/views/case_logs/_tasklist.html.erb
  5. 35
      config/forms/2021_2022.json
  6. 7
      db/migrate/20220706104313_add_unit_type_sh.rb
  7. 3
      db/schema.rb
  8. 2
      db/seeds.rb
  9. 2
      spec/factories/location.rb
  10. 2
      spec/features/form/tasklist_page_spec.rb
  11. 4
      spec/fixtures/exports/case_logs.csv
  12. 1
      spec/fixtures/exports/case_logs.xml
  13. 2
      spec/helpers/tasklist_helper_spec.rb
  14. 72
      spec/models/case_log_spec.rb

4
app/helpers/tasklist_helper.rb

@ -6,9 +6,9 @@ module TasklistHelper
end end
def get_subsections_count(case_log, status = :all) def get_subsections_count(case_log, status = :all)
return case_log.form.subsections.count if status == :all return case_log.form.subsections.count { |subsection| subsection.applicable_questions(case_log).count.positive? } if status == :all
case_log.form.subsections.count { |subsection| subsection.status(case_log) == status } case_log.form.subsections.count { |subsection| subsection.status(case_log) == status && subsection.applicable_questions(case_log).count.positive? }
end end
def next_page_or_check_answers(subsection, case_log, current_user) def next_page_or_check_answers(subsection, case_log, current_user)

28
app/models/derived_variables/case_log_variables.rb

@ -1,5 +1,13 @@
module DerivedVariables::CaseLogVariables module DerivedVariables::CaseLogVariables
RENT_TYPE_MAPPING = { 0 => 1, 1 => 2, 2 => 2, 3 => 3, 4 => 3, 5 => 3 }.freeze RENT_TYPE_MAPPING = { 0 => 1, 1 => 2, 2 => 2, 3 => 3, 4 => 3, 5 => 3 }.freeze
TYPE_OF_UNIT_MAP = {
"Self-contained flat or bedsit" => 1,
"Self-contained flat or bedsit with common facilities" => 2,
"Shared flat" => 3,
"Shared house or hostel" => 4,
"Bungalow" => 5,
"Self-contained house" => 6,
}.freeze
def supported_housing_schemes_enabled? def supported_housing_schemes_enabled?
FeatureToggle.supported_housing_schemes_enabled? FeatureToggle.supported_housing_schemes_enabled?
@ -8,7 +16,8 @@ module DerivedVariables::CaseLogVariables
def scheme_has_multiple_locations? def scheme_has_multiple_locations?
return false unless scheme return false unless scheme
scheme.locations.size > 1 @scheme_locations_count ||= scheme.locations.size
@scheme_locations_count > 1
end end
def set_derived_fields! def set_derived_fields!
@ -67,8 +76,21 @@ module DerivedVariables::CaseLogVariables
self.new_old = new_or_existing_tenant self.new_old = new_or_existing_tenant
self.vacdays = property_vacant_days self.vacdays = property_vacant_days
if is_supported_housing? && (scheme && scheme.locations.size == 1) if is_supported_housing? && scheme
self.location = scheme.locations.first if scheme.locations.size == 1
self.location = scheme.locations.first
end
if location
self.la = location.county
self.postcode_full = location.postcode
self.unittype_sh = TYPE_OF_UNIT_MAP[location.type_of_unit]
self.builtype = form.questions.find { |x| x.id == "builtype" }.answer_options.find { |_key, value| value["value"] == location.type_of_building }.first
wheelchair_adaptation_map = { 1 => 1, 0 => 2 }
self.wchair = wheelchair_adaptation_map[location.wheelchair_adaptation.to_i]
end
if is_renewal?
self.voiddate = startdate
end
end end
end end

2
app/models/form/subsection.rb

@ -34,7 +34,7 @@ class Form::Subsection
qs = applicable_questions(case_log) qs = applicable_questions(case_log)
qs_optional_removed = qs.reject { |q| case_log.optional_fields.include?(q.id) } qs_optional_removed = qs.reject { |q| case_log.optional_fields.include?(q.id) }
return :not_started if qs.all? { |question| case_log[question.id].blank? || question.read_only? || question.derived? } return :not_started if qs.count.positive? && qs.all? { |question| case_log[question.id].blank? || question.read_only? || question.derived? }
return :completed if qs_optional_removed.all? { |question| question.completed?(case_log) } return :completed if qs_optional_removed.all? { |question| question.completed?(case_log) }
:in_progress :in_progress

16
app/views/case_logs/_tasklist.html.erb

@ -9,13 +9,15 @@
<% end %> <% end %>
<ul class="app-task-list__items"> <ul class="app-task-list__items">
<% section.subsections.map do |subsection| %> <% section.subsections.map do |subsection| %>
<% subsection_status = subsection.status(@case_log) %> <% if subsection.applicable_questions(@case_log).count > 0 || !subsection.enabled?(@case_log) %>
<li class="app-task-list__item"> <% subsection_status = subsection.status(@case_log) %>
<span class="app-task-list__task-name" id="<%= subsection.id.dasherize %>"> <li class="app-task-list__item">
<%= subsection_link(subsection, @case_log, current_user) %> <span class="app-task-list__task-name" id="<%= subsection.id.dasherize %>">
</span> <%= subsection_link(subsection, @case_log, current_user) %>
<%= status_tag(subsection_status, "app-task-list__tag") %> </span>
</li> <%= status_tag(subsection_status, "app-task-list__tag") %>
</li>
<% end %>
<% end %> <% end %>
</ul> </ul>
</li> </li>

35
config/forms/2021_2022.json

@ -54,7 +54,12 @@
"value": "Not known" "value": "Not known"
} }
} }
} },
"depends_on": [
{
"needstype": 1
}
]
}, },
"property_local_authority": { "property_local_authority": {
"header": "", "header": "",
@ -388,7 +393,8 @@
}, },
"depends_on": [ "depends_on": [
{ {
"is_la_inferred": false "is_la_inferred": false,
"needstype": 1
} }
] ]
}, },
@ -617,7 +623,12 @@
} }
} }
} }
} },
"depends_on": [
{
"needstype": 1
}
]
}, },
"property_building_type": { "property_building_type": {
"header": "", "header": "",
@ -637,7 +648,12 @@
} }
} }
} }
} },
"depends_on": [
{
"needstype": 1
}
]
}, },
"property_wheelchair_accessible": { "property_wheelchair_accessible": {
"header": "", "header": "",
@ -657,7 +673,12 @@
} }
} }
} }
} },
"depends_on": [
{
"needstype": 1
}
]
}, },
"property_number_of_bedrooms": { "property_number_of_bedrooms": {
"header": "", "header": "",
@ -6840,7 +6861,9 @@
}, },
"net_income_value_check": { "net_income_value_check": {
"depends_on": [{ "net_income_soft_validation_triggered?": true }], "depends_on": [{ "net_income_soft_validation_triggered?": true }],
"title_text": { "translation": "soft_validations.net_income.title_text" }, "title_text": {
"translation": "soft_validations.net_income.title_text"
},
"informative_text": { "informative_text": {
"translation": "soft_validations.net_income.hint_text", "translation": "soft_validations.net_income.hint_text",
"arguments": [ "arguments": [

7
db/migrate/20220706104313_add_unit_type_sh.rb

@ -0,0 +1,7 @@
class AddUnitTypeSh < ActiveRecord::Migration[7.0]
def change
change_table :case_logs, bulk: true do |t|
t.integer :unittype_sh
end
end
end

3
db/schema.rb

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_07_05_130923) do ActiveRecord::Schema[7.0].define(version: 2022_07_06_104313) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -200,6 +200,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_05_130923) do
t.integer "vacdays" t.integer "vacdays"
t.bigint "scheme_id" t.bigint "scheme_id"
t.bigint "location_id" t.bigint "location_id"
t.integer "unittype_sh"
t.index ["created_by_id"], name: "index_case_logs_on_created_by_id" t.index ["created_by_id"], name: "index_case_logs_on_created_by_id"
t.index ["location_id"], name: "index_case_logs_on_location_id" t.index ["location_id"], name: "index_case_logs_on_location_id"
t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id"

2
db/seeds.rb

@ -115,7 +115,7 @@ unless Rails.env.test?
postcode: "CU193AA", postcode: "CU193AA",
name: "Rectory Road", name: "Rectory Road",
type_of_unit: 4, type_of_unit: 4,
type_of_building: "Purpose-built", type_of_building: "Purpose built",
county: "Mid Sussex", county: "Mid Sussex",
wheelchair_adaptation: 0, wheelchair_adaptation: 0,
) )

2
spec/factories/location.rb

@ -4,7 +4,7 @@ FactoryBot.define do
postcode { Faker::Address.postcode.delete(" ") } postcode { Faker::Address.postcode.delete(" ") }
name { Faker::Address.street_name } name { Faker::Address.street_name }
type_of_unit { Faker::Number.within(range: 1..6) } type_of_unit { Faker::Number.within(range: 1..6) }
type_of_building { Faker::Lorem.word } type_of_building { "Purpose built" }
wheelchair_adaptation { 0 } wheelchair_adaptation { 0 }
county { Faker::Address.state } county { Faker::Address.state }
scheme scheme

2
spec/features/form/tasklist_page_spec.rb

@ -54,7 +54,7 @@ RSpec.describe "Task List" do
it "shows number of completed sections if one section is completed" do it "shows number of completed sections if one section is completed" do
visit("/logs/#{setup_completed_log.id}") visit("/logs/#{setup_completed_log.id}")
expect(page).to have_content("1 of 9 sections completed.") expect(page).to have_content("1 of 8 sections completed.")
end end
it "show skip link for next incomplete section" do it "show skip link for next incomplete section" do

4
spec/fixtures/exports/case_logs.csv vendored

@ -1,2 +1,2 @@
status,tenancycode,age1,sex1,ethnic,national,prevten,ecstat1,hhmemb,age2,sex2,ecstat2,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,leftreg,reservist,illness,preg_occ,startertenancy,tenancylength,tenancy,ppostcode_full,rsnvac,unittype_gn,beds,offered,wchair,earnings,incfreq,benefits,period,layear,waityear,postcode_full,reasonpref,cbl,chr,cap,reasonother,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,illness_type_1,illness_type_2,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,irproduct_other,reason,propcode,la,prevloc,hb,hbrentshortfall,mrcdate,incref,startdate,armedforces,unitletas,builtype,voiddate,renttype,needstype,lettype,totchild,totelder,totadult,nocharge,referral,brent,scharge,pscharge,supcharg,tcharge,tshortfall,chcharge,ppcodenk,has_benefits,renewal,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat2,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,hhtype,new_old,vacdays,form,owningorgid,owningorgname,hcnum,maningorgid,maningorgname,manhcnum,createddate,uploaddate status,tenancycode,age1,sex1,ethnic,national,prevten,ecstat1,hhmemb,age2,sex2,ecstat2,age3,sex3,ecstat3,age4,sex4,ecstat4,age5,sex5,ecstat5,age6,sex6,ecstat6,age7,sex7,ecstat7,age8,sex8,ecstat8,homeless,underoccupation_benefitcap,leftreg,reservist,illness,preg_occ,startertenancy,tenancylength,tenancy,ppostcode_full,rsnvac,unittype_gn,beds,offered,wchair,earnings,incfreq,benefits,period,layear,waityear,postcode_full,reasonpref,cbl,chr,cap,reasonother,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,illness_type_1,illness_type_2,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,irproduct_other,reason,propcode,la,prevloc,hb,hbrentshortfall,mrcdate,incref,startdate,armedforces,unitletas,builtype,voiddate,renttype,needstype,lettype,totchild,totelder,totadult,nocharge,referral,brent,scharge,pscharge,supcharg,tcharge,tshortfall,chcharge,ppcodenk,has_benefits,renewal,wrent,wscharge,wpschrge,wsupchrg,wtcharge,wtshortfall,refused,housingneeds,wchchrg,newprop,relat2,relat3,relat4,relat5,relat6,relat7,relat8,lar,irproduct,joint,sheltered,hhtype,new_old,vacdays,unittype_sh,form,owningorgid,owningorgname,hcnum,maningorgid,maningorgname,manhcnum,createddate,uploaddate
2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,0,1,0,1,2,0,5,1,SE26RT,6,7,3,2,1,68,1,1,2,2,1,NW15TY,1,1,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05 10:36:49 UTC,0,2022-02-02 10:36:49 UTC,1,2,1,2019-11-03 00:00:00 UTC,2,1,7,0,0,2,0,,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,0,4,2,638,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-02-08 16:52:15 UTC,2022-02-08 16:52:15 UTC 2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,0,1,0,1,2,0,5,1,SE26RT,6,7,3,2,1,68,1,1,2,2,1,NW15TY,1,1,1,2,,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,,,4,123,E09000003,E07000105,6,1,2020-05-05 10:36:49 UTC,0,2022-02-02 10:36:49 UTC,1,2,1,2019-11-03 00:00:00 UTC,2,1,7,0,0,2,0,,200.0,50.0,40.0,35.0,325.0,12.0,,1,1,0,100.0,25.0,20.0,17.5,162.5,6.0,0,1,,2,P,,,,,,,,,,0,4,2,638,,{id},{owning_org_id},DLUHC,1234,{managing_org_id},DLUHC,1234,2022-02-08 16:52:15 UTC,2022-02-08 16:52:15 UTC

1 status tenancycode age1 sex1 ethnic national prevten ecstat1 hhmemb age2 sex2 ecstat2 age3 sex3 ecstat3 age4 sex4 ecstat4 age5 sex5 ecstat5 age6 sex6 ecstat6 age7 sex7 ecstat7 age8 sex8 ecstat8 homeless underoccupation_benefitcap leftreg reservist illness preg_occ startertenancy tenancylength tenancy ppostcode_full rsnvac unittype_gn beds offered wchair earnings incfreq benefits period layear waityear postcode_full reasonpref cbl chr cap reasonother housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h illness_type_1 illness_type_2 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 irproduct_other reason propcode la prevloc hb hbrentshortfall mrcdate incref startdate armedforces unitletas builtype voiddate renttype needstype lettype totchild totelder totadult nocharge referral brent scharge pscharge supcharg tcharge tshortfall chcharge ppcodenk has_benefits renewal wrent wscharge wpschrge wsupchrg wtcharge wtshortfall refused housingneeds wchchrg newprop relat2 relat3 relat4 relat5 relat6 relat7 relat8 lar irproduct joint sheltered hhtype new_old vacdays unittype_sh form owningorgid owningorgname hcnum maningorgid maningorgname manhcnum createddate uploaddate
2 2 BZ737 35 F 2 4 6 0 2 32 M 6 1 0 1 0 1 2 0 5 1 SE26RT 6 7 3 2 1 68 1 1 2 2 1 NW15TY 1 1 1 2 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 4 123 E09000003 E07000105 6 1 2020-05-05 10:36:49 UTC 0 2022-02-02 10:36:49 UTC 1 2 1 2019-11-03 00:00:00 UTC 2 1 7 0 0 2 0 200.0 50.0 40.0 35.0 325.0 12.0 1 1 0 100.0 25.0 20.0 17.5 162.5 6.0 0 1 2 P 0 4 2 638 {id} {owning_org_id} DLUHC 1234 {managing_org_id} DLUHC 1234 2022-02-08 16:52:15 UTC 2022-02-08 16:52:15 UTC

1
spec/fixtures/exports/case_logs.xml vendored

@ -135,6 +135,7 @@
<hhtype>4</hhtype> <hhtype>4</hhtype>
<new_old>2</new_old> <new_old>2</new_old>
<vacdays>638</vacdays> <vacdays>638</vacdays>
<unittype_sh/>
<form>{id}</form> <form>{id}</form>
<owningorgid>{owning_org_id}</owningorgid> <owningorgid>{owning_org_id}</owningorgid>
<owningorgname>DLUHC</owningorgname> <owningorgname>DLUHC</owningorgname>

2
spec/helpers/tasklist_helper_spec.rb

@ -17,7 +17,7 @@ RSpec.describe TasklistHelper do
describe "get sections count" do describe "get sections count" do
it "returns the total of sections if no status is given" do it "returns the total of sections if no status is given" do
expect(get_subsections_count(empty_case_log)).to eq(9) expect(get_subsections_count(empty_case_log)).to eq(8)
end end
it "returns 0 sections for completed sections if no sections are completed" do it "returns 0 sections for completed sections if no sections are completed" do

72
spec/models/case_log_spec.rb

@ -1680,7 +1680,12 @@ RSpec.describe CaseLog do
end end
context "when a case log is a supported housing log" do context "when a case log is a supported housing log" do
before { case_log.needstype = 2 } let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") }
before do
case_log.needstype = 2
allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form)
end
context "and a scheme with a single log is selected" do context "and a scheme with a single log is selected" do
let(:scheme) { FactoryBot.create(:scheme) } let(:scheme) { FactoryBot.create(:scheme) }
@ -1694,6 +1699,71 @@ RSpec.describe CaseLog do
expect(case_log["location_id"]).to eq(location.id) expect(case_log["location_id"]).to eq(location.id)
end end
end end
context "and not renewal" do
let(:scheme) { FactoryBot.create(:scheme) }
let(:location) { FactoryBot.create(:location, scheme:, county: "E07000041", type_of_unit: 1, type_of_building: "Purpose built", wheelchair_adaptation: 0) }
let!(:supported_housing_case_log) do
described_class.create!({
managing_organisation: owning_organisation,
owning_organisation:,
created_by: created_by_user,
needstype: 2,
scheme_id: scheme.id,
location_id: location.id,
renewal: 0,
})
end
it "correctly infers and saves la" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT la from case_logs WHERE id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["la"]).to eq(location.county)
end
it "correctly infers and saves postcode" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT postcode_full from case_logs WHERE id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["postcode_full"]).to eq(location.postcode)
end
it "correctly infers and saves type of unit" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT unittype_sh from case_logs WHERE id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["unittype_sh"]).to eq(1)
end
it "correctly infers and saves type of building" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT builtype from case_logs WHERE id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["builtype"]).to eq(1)
end
it "correctly infers and saves wchair" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT wchair from case_logs WHERE id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["wchair"]).to eq(2)
end
end
context "and renewal" do
let(:scheme) { FactoryBot.create(:scheme) }
let(:location) { FactoryBot.create(:location, scheme:) }
let!(:supported_housing_case_log) do
described_class.create!({
managing_organisation: owning_organisation,
owning_organisation:,
created_by: created_by_user,
needstype: 2,
scheme_id: scheme.id,
location_id: location.id,
renewal: 1,
startdate: Time.zone.now,
})
end
it "correcly infers and saves the renewal date" do
record_from_db = ActiveRecord::Base.connection.execute("SELECT voiddate from case_logs where id=#{supported_housing_case_log.id}").to_a[0]
expect(record_from_db["voiddate"].to_i).to eq(supported_housing_case_log.startdate.to_i)
end
end
end end
end end

Loading…
Cancel
Save