diff --git a/app/services/imports/lettings_logs_field_import_service.rb b/app/services/imports/lettings_logs_field_import_service.rb index db705d990..82e359423 100644 --- a/app/services/imports/lettings_logs_field_import_service.rb +++ b/app/services/imports/lettings_logs_field_import_service.rb @@ -312,36 +312,57 @@ module Imports if (2..record.hhmemb).all? { |person_index| record.has_any_person_details?(person_index) || record["details_known_#{person_index}"] == 1 } return @logger.info("lettings log #{record.id} has all household member details, skipping update") end + if record.hhmemb == 8 || (record.hhmemb + 1..8).none? { |person_index| file_contains_person_details?(xml_doc, person_index) } + return @logger.info("lettings log #{record.id} has no additional household member details, skipping update") + end - (2..record.hhmemb - 1).each do |person_index| - if record.has_any_person_details?(person_index) || record["details_known_#{person_index}"] == 1 - @logger.info("lettings log #{record.id} has details for person #{person_index}, skipping update") - next - end + person_index = 2 + next_person_index = person_index + 1 - record["details_known_#{person_index}"] = record["details_known_#{person_index + 1}"] - record["age#{person_index}"] = record["age#{person_index + 1}"] - record["age#{person_index}_known"] = record["age#{person_index + 1}_known"] - record["sex#{person_index}"] = record["sex#{person_index + 1}"] - record["ecstat#{person_index}"] = record["ecstat#{person_index + 1}"] - record["relat#{person_index}"] = record["relat#{person_index + 1}"] - record["details_known_#{person_index + 1}"] = nil - record["age#{person_index + 1}"] = nil - record["age#{person_index + 1}_known"] = nil - record["sex#{person_index + 1}"] = nil - record["ecstat#{person_index + 1}"] = nil - record["relat#{person_index + 1}"] = nil - - @logger.info("lettings log #{record.id}'s person #{person_index + 1} details moved to person #{person_index} details") - end + while person_index <= record.hhmemb + if next_person_index <= record.hhmemb + if record.has_any_person_details?(person_index) || record["details_known_#{person_index}"] == 1 + @logger.info("lettings log #{record.id} has details for person #{person_index}, skipping update") + person_index += 1 + next_person_index += 1 + next + end + + if !record.has_any_person_details?(next_person_index) && record["details_known_#{next_person_index}"] != 1 + next_person_index += 1 + next + end + + record["details_known_#{person_index}"] = record["details_known_#{next_person_index}"] + record["age#{person_index}"] = record["age#{next_person_index}"] + record["age#{person_index}_known"] = record["age#{next_person_index}_known"] + record["sex#{person_index}"] = record["sex#{next_person_index}"] + record["ecstat#{person_index}"] = record["ecstat#{next_person_index}"] + record["relat#{person_index}"] = record["relat#{next_person_index}"] + + record["details_known_#{next_person_index}"] = nil + record["age#{next_person_index}"] = nil + record["age#{next_person_index}_known"] = nil + record["sex#{next_person_index}"] = nil + record["ecstat#{next_person_index}"] = nil + record["relat#{next_person_index}"] = nil + + @logger.info("lettings log #{record.id}'s person #{next_person_index} details moved to person #{person_index} details") - record["age#{record.hhmemb}"] = safe_string_as_integer(xml_doc, "P#{record.hhmemb + 1}Age") - record["age#{record.hhmemb}_known"] = age_known(xml_doc, record.hhmemb + 1) - record["sex#{record.hhmemb}"] = sex(xml_doc, record.hhmemb + 1) - record["ecstat#{record.hhmemb}"] = unsafe_string_as_integer(xml_doc, "P#{record.hhmemb + 1}Eco") - record["relat#{record.hhmemb}"] = relat(xml_doc, record.hhmemb + 1) - record["details_known_#{record.hhmemb}"] = record.has_any_person_details?(record.hhmemb) ? 0 : 1 - @logger.info("lettings log #{record.id}, reimported person #{record.hhmemb} details") + person_index += 1 + next_person_index += 1 + else + record["age#{person_index}"] = safe_string_as_integer(xml_doc, "P#{next_person_index}Age") + record["age#{person_index}_known"] = age_known(xml_doc, next_person_index) + record["sex#{person_index}"] = sex(xml_doc, next_person_index) + record["ecstat#{person_index}"] = unsafe_string_as_integer(xml_doc, "P#{next_person_index}Eco") + record["relat#{person_index}"] = relat(xml_doc, next_person_index) + record["details_known_#{person_index}"] = details_known(person_index, record) + @logger.info("lettings log #{record.id}, reimported person #{person_index} details") + person_index += 1 + next_person_index += 1 + end + end record.values_updated_at = Time.zone.now record.save! @@ -358,5 +379,23 @@ module Imports end 0 end + + def details_known(index, record) + if record["age#{index}_known"] == 1 && + record["sex#{index}"] == "R" && + record["relat#{index}"] == "R" && + record["ecstat#{index}"] == 10 + 1 # No + else + 0 # Yes + end + end + + def file_contains_person_details?(xml_doc, person_index) + safe_string_as_integer(xml_doc, "P#{person_index}Age").present? || + string_or_nil(xml_doc, "P#{person_index}Sex").present? || + unsafe_string_as_integer(xml_doc, "P#{person_index}Eco").present? || + string_or_nil(xml_doc, "P#{person_index}Rel").present? + end end end diff --git a/spec/services/imports/lettings_logs_field_import_service_spec.rb b/spec/services/imports/lettings_logs_field_import_service_spec.rb index 02fc17192..ae0b610a4 100644 --- a/spec/services/imports/lettings_logs_field_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_field_import_service_spec.rb @@ -1039,6 +1039,8 @@ RSpec.describe Imports::LettingsLogsFieldImportService do lettings_log_xml.at_xpath("//xmlns:P7Sex").content = "Male" lettings_log_xml.at_xpath("//xmlns:P7Rel").content = "Child" lettings_log_xml.at_xpath("//xmlns:P7Eco").content = "9) Child under 16" + + lettings_log_xml.at_xpath("//xmlns:P8Age").content = 21 end context "when the lettings log has no details for person 2" do @@ -1177,6 +1179,116 @@ RSpec.describe Imports::LettingsLogsFieldImportService do end end + context "when the lettings log has no details for several consecutive household members" do + before do + lettings_log.update(details_known_2: 1, age2_known: nil, age2: nil, sex2: nil, ecstat2: nil, relat2: nil, hhmemb: 6, + details_known_3: 0, age3_known: 0, age3: 19, sex3: "F", ecstat3: 10, relat3: "X", + details_known_4: 0, age4_known: nil, age4: nil, sex4: nil, ecstat4: nil, relat4: nil, + details_known_5: 0, age5_known: nil, age5: nil, sex5: nil, ecstat5: nil, relat5: nil, + details_known_6: 0, age6_known: 0, age6: 22, sex6: "R", ecstat6: 10, relat6: "R") + end + + it "moves the details of all the relevant household members" do + expect(logger).to receive(:info).with(/lettings log \d+ has details for person 2, skipping update/) + expect(logger).to receive(:info).with(/lettings log \d+ has details for person 3, skipping update/) + expect(logger).to receive(:info).with(/lettings log \d+'s person 6 details moved to person 4 details/) + expect(logger).to receive(:info).with(/lettings log \d+, reimported person 5 details/) + expect(logger).to receive(:info).with(/lettings log \d+, reimported person 6 details/) + import_service.send(:update_person_details, lettings_log_xml) + lettings_log.reload + expect(lettings_log.details_known_2).to eq(1) + expect(lettings_log.age2_known).to eq(nil) + expect(lettings_log.age2).to eq(nil) + expect(lettings_log.sex2).to eq(nil) + expect(lettings_log.ecstat2).to eq(nil) + expect(lettings_log.relat2).to eq(nil) + + expect(lettings_log.age3_known).to eq(0) + expect(lettings_log.age3).to eq(19) + expect(lettings_log.sex3).to eq("F") + expect(lettings_log.ecstat3).to eq(10) + expect(lettings_log.relat3).to eq("X") + + expect(lettings_log.details_known_4).to eq(0) + expect(lettings_log.age4_known).to eq(0) + expect(lettings_log.age4).to eq(22) + expect(lettings_log.sex4).to eq("R") + expect(lettings_log.ecstat4).to eq(10) + expect(lettings_log.relat4).to eq("R") + + expect(lettings_log.details_known_5).to eq(0) + expect(lettings_log.age5_known).to eq(0) + expect(lettings_log.age5).to eq(7) + expect(lettings_log.sex5).to eq("M") + expect(lettings_log.ecstat5).to eq(9) + expect(lettings_log.relat5).to eq("C") + + expect(lettings_log.details_known_6).to eq(0) + expect(lettings_log.age6_known).to eq(0) + expect(lettings_log.age6).to eq(21) + expect(lettings_log.sex6).to eq(nil) + expect(lettings_log.ecstat6).to eq(nil) + expect(lettings_log.relat6).to eq(nil) + + expect(lettings_log.values_updated_at).not_to be_nil + end + end + + context "when the lettings log has no details for several non consecutive household members" do + before do + lettings_log.update(details_known_2: 0, age2_known: nil, age2: nil, sex2: nil, ecstat2: nil, relat2: nil, hhmemb: 6, + details_known_3: 0, age3_known: 0, age3: 19, sex3: "F", ecstat3: 10, relat3: "X", + details_known_4: 1, age4_known: nil, age4: nil, sex4: nil, ecstat4: nil, relat4: nil, + details_known_5: 0, age5_known: nil, age5: nil, sex5: nil, ecstat5: nil, relat5: nil, + details_known_6: 0, age6_known: 0, age6: 22, sex6: "R", ecstat6: 10, relat6: "R") + end + + it "moves the details of all the relevant household members" do + expect(logger).to receive(:info).with(/lettings log \d+'s person 3 details moved to person 2 details/) + expect(logger).to receive(:info).with(/lettings log \d+'s person 4 details moved to person 3 details/) + expect(logger).to receive(:info).with(/lettings log \d+'s person 6 details moved to person 4 details/) + expect(logger).to receive(:info).with(/lettings log \d+, reimported person 5 details/) + expect(logger).to receive(:info).with(/lettings log \d+, reimported person 6 details/) + import_service.send(:update_person_details, lettings_log_xml) + lettings_log.reload + expect(lettings_log.age2_known).to eq(0) + expect(lettings_log.age2).to eq(19) + expect(lettings_log.sex2).to eq("F") + expect(lettings_log.ecstat2).to eq(10) + expect(lettings_log.relat2).to eq("X") + + expect(lettings_log.details_known_3).to eq(1) + expect(lettings_log.age3_known).to eq(nil) + expect(lettings_log.age3).to eq(nil) + expect(lettings_log.sex3).to eq(nil) + expect(lettings_log.ecstat3).to eq(nil) + expect(lettings_log.relat3).to eq(nil) + + expect(lettings_log.details_known_4).to eq(0) + expect(lettings_log.age4_known).to eq(0) + expect(lettings_log.age4).to eq(22) + expect(lettings_log.sex4).to eq("R") + expect(lettings_log.ecstat4).to eq(10) + expect(lettings_log.relat4).to eq("R") + + expect(lettings_log.details_known_5).to eq(0) + expect(lettings_log.age5_known).to eq(0) + expect(lettings_log.age5).to eq(7) + expect(lettings_log.sex5).to eq("M") + expect(lettings_log.ecstat5).to eq(9) + expect(lettings_log.relat5).to eq("C") + + expect(lettings_log.details_known_6).to eq(0) + expect(lettings_log.age6_known).to eq(0) + expect(lettings_log.age6).to eq(21) + expect(lettings_log.sex6).to eq(nil) + expect(lettings_log.ecstat6).to eq(nil) + expect(lettings_log.relat6).to eq(nil) + + expect(lettings_log.values_updated_at).not_to be_nil + end + end + context "when the lettings log has details for person 2" do let(:lettings_log) { LettingsLog.find_by(old_id: lettings_log_id) } @@ -1206,5 +1318,24 @@ RSpec.describe Imports::LettingsLogsFieldImportService do expect(lettings_log.values_updated_at).to be_nil end end + + context "when none of the details past hhmemb are given in the reimport" do + let(:lettings_log) { LettingsLog.find_by(old_id: lettings_log_id) } + + before do + lettings_log.update!(hhmemb: 7) + lettings_log_xml.at_xpath("//xmlns:P8Age").content = "" + lettings_log_xml.at_xpath("//xmlns:P8Sex").content = "" + lettings_log_xml.at_xpath("//xmlns:P8Rel").content = "" + lettings_log_xml.at_xpath("//xmlns:P8Eco").content = "" + end + + it "does not update the lettings_log person details" do + expect(logger).to receive(:info).with(/lettings log \d+ has no additional household member details, skipping update/) + import_service.send(:update_person_details, lettings_log_xml) + lettings_log.reload + expect(lettings_log.values_updated_at).to be_nil + end + end end end