From 4cd5b519b57c46dd39623c917c0e0680e231d4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Meny?= Date: Thu, 21 Jul 2022 09:29:47 +0100 Subject: [PATCH] CLDC-1228: SH export (#764) * Add new export fields for supported housing * Makes unitletas (most recent let type) general needs only --- .../exports/case_log_export_constants.rb | 2 + .../exports/case_log_export_service.rb | 34 +++- app/views/schemes/details.html.erb | 2 +- config/forms/2021_2022.json | 3 +- config/forms/2022_2023.json | 3 +- spec/factories/case_log.rb | 22 ++- spec/factories/location.rb | 9 + spec/factories/scheme.rb | 9 + .../{case_logs.csv => general_needs_log.csv} | 4 +- .../{case_logs.xml => general_needs_log.xml} | 7 +- .../exports/supported_housing_logs.xml | 161 ++++++++++++++++++ .../exports/case_log_export_service_spec.rb | 32 +++- 12 files changed, 268 insertions(+), 20 deletions(-) rename spec/fixtures/exports/{case_logs.csv => general_needs_log.csv} (86%) rename spec/fixtures/exports/{case_logs.xml => general_needs_log.xml} (97%) create mode 100644 spec/fixtures/exports/supported_housing_logs.xml diff --git a/app/services/exports/case_log_export_constants.rb b/app/services/exports/case_log_export_constants.rb index 1f8770d29..9a698d58d 100644 --- a/app/services/exports/case_log_export_constants.rb +++ b/app/services/exports/case_log_export_constants.rb @@ -55,6 +55,7 @@ module Exports::CaseLogExportConstants "manhcnum", "maningorgid", "maningorgname", + "mantype", "mobstand", "mrcdate", "national", @@ -111,6 +112,7 @@ module Exports::CaseLogExportConstants "underoccupation_benefitcap", "unitletas", "units", + "units_scheme", "unittype_gn", "unittype_sh", "uploaddate", diff --git a/app/services/exports/case_log_export_service.rb b/app/services/exports/case_log_export_service.rb index d2e031e90..7a6918831 100644 --- a/app/services/exports/case_log_export_service.rb +++ b/app/services/exports/case_log_export_service.rb @@ -165,12 +165,12 @@ module Exports end # Organisation fields - if case_log.owning_organisation.present? + if case_log.owning_organisation attribute_hash["owningorgid"] = case_log.owning_organisation.old_visible_id || (case_log.owning_organisation.id + LOG_ID_OFFSET) attribute_hash["owningorgname"] = case_log.owning_organisation.name attribute_hash["hcnum"] = case_log.owning_organisation.housing_registration_no end - if case_log.managing_organisation.present? + if case_log.managing_organisation attribute_hash["maningorgid"] = case_log.managing_organisation.old_visible_id || (case_log.managing_organisation.id + LOG_ID_OFFSET) attribute_hash["maningorgname"] = case_log.managing_organisation.name attribute_hash["manhcnum"] = case_log.managing_organisation.housing_registration_no @@ -189,11 +189,37 @@ module Exports attribute_hash["age#{index}"] = -9 if attribute_hash["age#{index}_known"] == 1 end - attribute_hash["unittype_sh"] = case_log.unittype_sh - + # Supported housing fields + if case_log.is_supported_housing? + attribute_hash["unittype_sh"] = case_log.unittype_sh + attribute_hash["sheltered"] = case_log.sheltered + attribute_hash["nocharge"] = case_log.household_charge == 1 ? 1 : nil + attribute_hash["chcharge"] = case_log.chcharge + add_scheme_fields!(case_log.scheme, attribute_hash) + add_location_fields!(case_log.location, attribute_hash) + attribute_hash.delete("unittype_gn") + end attribute_hash end + def add_scheme_fields!(scheme, attribute_hash) + attribute_hash["confidential"] = scheme.sensitive_before_type_cast == 1 ? 1 : nil + attribute_hash["cligrp1"] = scheme.primary_client_group_before_type_cast + attribute_hash["cligrp2"] = scheme.secondary_client_group_before_type_cast + attribute_hash["intstay"] = scheme.intended_stay_before_type_cast + attribute_hash["mantype"] = scheme.arrangement_type_before_type_cast + attribute_hash["reghome"] = scheme.registered_under_care_act_before_type_cast + attribute_hash["schtype"] = scheme.scheme_type_before_type_cast + attribute_hash["support"] = scheme.support_type_before_type_cast + attribute_hash["units_scheme"] = scheme.locations.map(&:units).sum + end + + def add_location_fields!(location, attribute_hash) + attribute_hash["mobstand"] = location.mobility_type_before_type_cast + attribute_hash["scheme"] = location.old_visible_id || (location.id + LOG_ID_OFFSET) + attribute_hash["units"] = location.units + end + def filter_keys!(attributes) attributes.reject! { |attribute| is_omitted_field?(attribute) } end diff --git a/app/views/schemes/details.html.erb b/app/views/schemes/details.html.erb index dd05c4a00..206b26271 100644 --- a/app/views/schemes/details.html.erb +++ b/app/views/schemes/details.html.erb @@ -1,4 +1,4 @@ -<% content_for :title, "Create a new supported housing scheme" %> + <% content_for :title, "Create a new supported housing scheme" %> <% content_for :before_content do %> <%= govuk_back_link( diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index fac033857..7765ce9ba 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -456,7 +456,8 @@ "depends_on": [ { "first_time_property_let_as_social_housing": 0, - "renewal": 0 + "renewal": 0, + "needstype": 1 } ] }, diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index db26c7d0f..3890b1dbf 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -456,7 +456,8 @@ "depends_on": [ { "first_time_property_let_as_social_housing": 0, - "renewal": 0 + "renewal": 0, + "needstype": 1 } ] }, diff --git a/spec/factories/case_log.rb b/spec/factories/case_log.rb index 43a1b15a8..ec2d2c522 100644 --- a/spec/factories/case_log.rb +++ b/spec/factories/case_log.rb @@ -38,14 +38,18 @@ FactoryBot.define do trait :completed do status { 2 } tenancycode { Faker::Name.initials(number: 10) } + age1_known { 0 } age1 { 35 } sex1 { "F" } + ethnic_group { 0 } ethnic { 2 } national { 4 } prevten { 6 } ecstat1 { 0 } hhmemb { 2 } relat2 { "P" } + age2_known { 0 } + details_known_2 { 0 } age2 { 32 } sex2 { "M" } ecstat2 { 6 } @@ -55,7 +59,7 @@ FactoryBot.define do reservist { 0 } illness { 1 } preg_occ { 2 } - startertenancy { 0 } + startertenancy { 1 } tenancylength { 5 } tenancy { 1 } ppostcode_full { Faker::Address.postcode } @@ -106,7 +110,7 @@ FactoryBot.define do rp_dontknow { 0 } tenancyother { nil } net_income_value_check { nil } - net_income_known { 1 } + net_income_known { 0 } previous_la_known { 1 } property_owner_organisation { "Test" } property_manager_organisation { "Test" } @@ -132,8 +136,20 @@ FactoryBot.define do unitletas { 2 } has_benefits { 1 } is_carehome { 0 } - sheltered { 0 } declaration { 1 } + first_time_property_let_as_social_housing { 0 } + referral { 2 } + end + trait :export do + tenancycode { "987654" } + ppostcode_full { "LE5 1QP" } + propcode { "MYPROP" } + tenancylength { nil } + end + trait :sh do + needstype { 2 } + sheltered { 0 } + household_charge { 0 } end created_at { Time.utc(2022, 2, 8, 16, 52, 15) } updated_at { Time.utc(2022, 2, 8, 16, 52, 15) } diff --git a/spec/factories/location.rb b/spec/factories/location.rb index ed333f8de..08a43c1f8 100644 --- a/spec/factories/location.rb +++ b/spec/factories/location.rb @@ -7,5 +7,14 @@ FactoryBot.define do type_of_building { "Purpose built" } mobility_type { %w[A M N W X].sample } scheme + trait :export do + postcode { "SW1A 2AA" } + name { "Downing Street" } + type_of_unit { 7 } + units { 20 } + mobility_type { "A" } + scheme { FactoryBot.create(:scheme, :export) } + old_visible_id { 111 } + end end end diff --git a/spec/factories/scheme.rb b/spec/factories/scheme.rb index c27b8a576..e94fb886f 100644 --- a/spec/factories/scheme.rb +++ b/spec/factories/scheme.rb @@ -10,5 +10,14 @@ FactoryBot.define do 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) } created_at { Time.zone.now } + trait :export do + sensitive { 1 } + registered_under_care_act { 1 } + support_type { 4 } + scheme_type { 7 } + intended_stay { "M" } + primary_client_group { "G" } + secondary_client_group { "M" } + end end end diff --git a/spec/fixtures/exports/case_logs.csv b/spec/fixtures/exports/general_needs_log.csv similarity index 86% rename from spec/fixtures/exports/case_logs.csv rename to spec/fixtures/exports/general_needs_log.csv index c13929611..e38480513 100644 --- a/spec/fixtures/exports/case_logs.csv +++ b/spec/fixtures/exports/general_needs_log.csv @@ -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,unittype_sh -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, +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 +2,BZ737,35,F,2,4,6,0,2,32,M,6,,,,,,,,,,,,,,,,,,,1,0,1,0,1,2,1,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,2,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,,,,,,,,,,,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 diff --git a/spec/fixtures/exports/case_logs.xml b/spec/fixtures/exports/general_needs_log.xml similarity index 97% rename from spec/fixtures/exports/case_logs.xml rename to spec/fixtures/exports/general_needs_log.xml index a4089db67..b7d969c41 100644 --- a/spec/fixtures/exports/case_logs.xml +++ b/spec/fixtures/exports/general_needs_log.xml @@ -37,7 +37,7 @@ 0 1 2 - 0 + 1 5 1 SE26RT @@ -101,7 +101,7 @@ 0 2 0 - + 2 200.0 50.0 40.0 @@ -131,7 +131,7 @@ - 0 + 4 2 638 @@ -144,7 +144,6 @@ 1234 2022-02-08 16:52:15 UTC 2022-02-08 16:52:15 UTC - 1 diff --git a/spec/fixtures/exports/supported_housing_logs.xml b/spec/fixtures/exports/supported_housing_logs.xml new file mode 100644 index 000000000..5e2309871 --- /dev/null +++ b/spec/fixtures/exports/supported_housing_logs.xml @@ -0,0 +1,161 @@ + + +
+ 2 + 987654 + 35 + F + 2 + 4 + 6 + 0 + 2 + 32 + M + 6 + + + + + + + + + + + + + + + + + + + 1 + 0 + 1 + 0 + 1 + 2 + 1 + + 1 + LE51QP + 6 + + 2 + 2 + 68 + 1 + 1 + 2 + 2 + 1 + SW1A2AA + 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 + MYPROP + E09000003 + E07000105 + 6 + 1 + 2020-05-05 10:36:49 UTC + 0 + 2022-02-02 10:36:49 UTC + 1 + + + 2019-11-03 00:00:00 UTC + 2 + 2 + 8 + 0 + 0 + 2 + + 2 + 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 + 7 + 1 + G + M + M + + 1 + 7 + 4 + 20 + A + 111 + 20 + 1 + +
diff --git a/spec/services/exports/case_log_export_service_spec.rb b/spec/services/exports/case_log_export_service_spec.rb index a00ed6e49..36a17fa5d 100644 --- a/spec/services/exports/case_log_export_service_spec.rb +++ b/spec/services/exports/case_log_export_service_spec.rb @@ -5,12 +5,16 @@ RSpec.describe Exports::CaseLogExportService do let(:storage_service) { instance_double(StorageService) } - let(:xml_export_file) { File.open("spec/fixtures/exports/case_logs.xml", "r:UTF-8") } + let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log.xml", "r:UTF-8") } let(:local_manifest_file) { File.open("spec/fixtures/exports/manifest.xml", "r:UTF-8") } + let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") } + let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json", "2022_2023") } + let(:expected_master_manifest_filename) { "Manifest_2022_05_01_0001.csv" } let(:expected_master_manifest_rerun) { "Manifest_2022_05_01_0002.csv" } let(:expected_zip_filename) { "core_2021_2022_jan_mar_f0001_inc0001.zip" } + let(:expected_data_filename) { "core_2021_2022_jan_mar_f0001_inc0001_pt001.xml" } let(:expected_manifest_filename) { "manifest.xml" } let(:start_time) { Time.zone.local(2022, 5, 1) } @@ -27,6 +31,10 @@ RSpec.describe Exports::CaseLogExportService do before do Timecop.freeze(start_time) allow(storage_service).to receive(:write_file) + + # Stub the form handler to use the real form + allow(FormHandler.instance).to receive(:get_form).with("2021_2022").and_return(real_2021_2022_form) + allow(FormHandler.instance).to receive(:get_form).with("2022_2023").and_return(real_2022_2023_form) end context "when exporting daily case logs in XML" do @@ -48,7 +56,6 @@ RSpec.describe Exports::CaseLogExportService do context "and one case log is available for export" do let!(:case_log) { FactoryBot.create(:case_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737") } - let(:expected_data_filename) { "core_2021_2022_jan_mar_f0001_inc0001_pt001.xml" } it "generates a ZIP export file with the expected filename" do expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args) @@ -222,8 +229,8 @@ RSpec.describe Exports::CaseLogExportService do end end - context "when export case logs in CSV" do - let(:csv_export_file) { File.open("spec/fixtures/exports/case_logs.csv", "r:UTF-8") } + context "when exporting a general needs case logs in CSV" do + let(:csv_export_file) { File.open("spec/fixtures/exports/general_needs_log.csv", "r:UTF-8") } let(:expected_csv_filename) { "export_2022_05_01.csv" } let(:case_log) { FactoryBot.create(:case_log, :completed, propcode: "123", ppostcode_full: "SE2 6RT", postcode_full: "NW1 5TY", tenancycode: "BZ737") } @@ -237,4 +244,21 @@ RSpec.describe Exports::CaseLogExportService do export_service.export_csv_case_logs end end + + context "when exporting a supporting housing case logs in XML" do + let(:export_file) { File.open("spec/fixtures/exports/supported_housing_logs.xml", "r:UTF-8") } + let(:location) { FactoryBot.create(:location, :export) } + + let(:case_log) { FactoryBot.create(:case_log, :completed, :export, :sh, scheme: location.scheme, location:) } + + it "generates an XML export file with the expected content" do + expected_content = replace_entity_ids(case_log, export_file.read) + expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args) do |_, content| + entry = Zip::File.open_buffer(content).find_entry(expected_data_filename) + expect(entry).not_to be_nil + expect(entry.get_input_stream.read).to eq(expected_content) + end + export_service.export_xml_case_logs(full_update: true) + end + end end