Browse Source

Remove import code (#2047)

* Move rent type to lettings log model

* Remove import and old rake tasks
pull/2052/head
kosiakkatrina 1 year ago committed by GitHub
parent
commit
fe98d89042
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      app/models/lettings_log.rb
  2. 12
      app/services/bulk_upload/lettings/year2022/row_parser.rb
  3. 12
      app/services/bulk_upload/lettings/year2023/row_parser.rb
  4. 61
      app/services/imports/data_protection_confirmation_import_service.rb
  5. 152
      app/services/imports/import_report_service.rb
  6. 51
      app/services/imports/import_service.rb
  7. 482
      app/services/imports/lettings_logs_field_import_service.rb
  8. 698
      app/services/imports/lettings_logs_import_service.rb
  9. 128
      app/services/imports/logs_import_service.rb
  10. 53
      app/services/imports/organisation_import_service.rb
  11. 22
      app/services/imports/organisation_rent_period_import_service.rb
  12. 95
      app/services/imports/sales_logs_field_import_service.rb
  13. 666
      app/services/imports/sales_logs_import_service.rb
  14. 62
      app/services/imports/scheme_import_service.rb
  15. 222
      app/services/imports/scheme_location_import_service.rb
  16. 100
      app/services/imports/user_import_service.rb
  17. 4
      lib/tasks/blank_migrated_soctenant_values.rake
  18. 14
      lib/tasks/confirm_charges_soft_validations.rake
  19. 5
      lib/tasks/correct_has_other_client_group_values.rake
  20. 6
      lib/tasks/correct_incref_values.rake
  21. 6
      lib/tasks/correct_location_admin_district.rake
  22. 10
      lib/tasks/correct_min_age_values.rake
  23. 6
      lib/tasks/correct_ppcodenk_values.rake
  24. 31
      lib/tasks/data_import.rake
  25. 45
      lib/tasks/data_import_field.rake
  26. 175
      lib/tasks/full_import.rake
  27. 18
      lib/tasks/recalculate_irproduct_values.rake
  28. 13
      lib/tasks/recalculate_lar_values.rake
  29. 12
      lib/tasks/recalculate_refused_values.rake
  30. 22
      lib/tasks/remove_placeholder_deactivations.rake
  31. 35
      lib/tasks/squish_names.rake
  32. 11
      lib/tasks/sync_legacy_users.rake
  33. 16
      spec/fixtures/files/imported_lettings_logs_missing_answers_examples.csv
  34. 4
      spec/fixtures/files/imported_lettings_logs_missing_answers_report.csv
  35. 7
      spec/fixtures/imports/dataprotect/7c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml
  36. 23
      spec/fixtures/imports/institution/7c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml
  37. 23
      spec/fixtures/imports/institution/8c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml
  38. 515
      spec/fixtures/imports/logs/00d2343e-d5fa-4c89-8400-ec3854b0f2b4.xml
  39. 524
      spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml
  40. 533
      spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml
  41. 515
      spec/fixtures/imports/logs/166fc004-392e-47a8-acb8-1c018734882b.xml
  42. 514
      spec/fixtures/imports/logs/5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd.xml
  43. 514
      spec/fixtures/imports/logs/893ufj2s-lq77-42m4-rty6-ej09gh585uy1.xml
  44. 333
      spec/fixtures/imports/logs/shared_ownership_sales_log.xml
  45. 9
      spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml
  46. 5
      spec/fixtures/imports/rent-period/ebd22326d33e389e9f1bfd546979d2c05f9e68d6.xml
  47. 350
      spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml
  48. 524
      spec/fixtures/imports/sales_logs/lettings_log.xml
  49. 339
      spec/fixtures/imports/sales_logs/outright_sale_sales_log.xml
  50. 342
      spec/fixtures/imports/sales_logs/shared_ownership_sales_log.xml
  51. 334
      spec/fixtures/imports/sales_logs/shared_ownership_sales_log2.xml
  52. 333
      spec/fixtures/imports/sales_logs/shared_ownership_sales_log3.xml
  53. 333
      spec/fixtures/imports/sales_logs/shared_ownership_sales_log4.xml
  54. 25
      spec/fixtures/imports/schemes/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml
  55. 23
      spec/fixtures/imports/schemes/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml
  56. 13
      spec/fixtures/imports/user/10c887710550844e2551b3e0fb88dc9b4a8a642b.xml
  57. 19
      spec/fixtures/imports/user/80d9b73aa1c88b6e5c36ee49be9050b923b4a1bb.xml
  58. 13
      spec/fixtures/imports/user/9ed81a262215a1634f0809effa683e38924d8bcb.xml
  59. 13
      spec/fixtures/imports/user/b7829b1a5dfb68bb1e01c08445830c0add40907c.xml
  60. 13
      spec/fixtures/imports/user/d4729b1a5dfb68bb1e01c08445830c0add40907c.xml
  61. 13
      spec/fixtures/imports/user/d6717836154cd9a58f9e2f1d3077e3ab81e07613.xml
  62. 13
      spec/fixtures/imports/user/fc7625a02b24ae16162aa63ae7cb33feeec0c373.xml
  63. 76
      spec/lib/tasks/blank_migrated_soctenant_values_spec.rb
  64. 165
      spec/lib/tasks/confirm_charges_soft_validations_spec.rb
  65. 56
      spec/lib/tasks/correct_has_other_client_group_values_spec.rb
  66. 52
      spec/lib/tasks/correct_incref_values_spec.rb
  67. 52
      spec/lib/tasks/correct_location_admin_district_spec.rb
  68. 80
      spec/lib/tasks/correct_min_age_values_spec.rb
  69. 67
      spec/lib/tasks/correct_ppcodenk_values_spec.rb
  70. 338
      spec/lib/tasks/data_import_field_spec.rb
  71. 191
      spec/lib/tasks/data_import_spec.rb
  72. 144
      spec/lib/tasks/full_import_spec.rb
  73. 132
      spec/lib/tasks/recalculate_irproduct_values_spec.rb
  74. 100
      spec/lib/tasks/recalculate_lar_values_spec.rb
  75. 84
      spec/lib/tasks/recalculate_refused_values_spec.rb
  76. 54
      spec/lib/tasks/remove_placeholder_deactivations_spec.rb
  77. 65
      spec/lib/tasks/squish_names_spec.rb
  78. 97
      spec/services/imports/data_protection_confirmation_import_service_spec.rb
  79. 185
      spec/services/imports/import_report_service_spec.rb
  80. 1573
      spec/services/imports/lettings_logs_field_import_service_spec.rb
  81. 2160
      spec/services/imports/lettings_logs_import_service_spec.rb
  82. 153
      spec/services/imports/organisation_import_service_spec.rb
  83. 42
      spec/services/imports/organisation_rent_period_import_service_spec.rb
  84. 238
      spec/services/imports/sales_logs_field_import_service_spec.rb
  85. 2327
      spec/services/imports/sales_logs_import_service_spec.rb
  86. 74
      spec/services/imports/scheme_import_service_spec.rb
  87. 251
      spec/services/imports/scheme_location_import_service_spec.rb
  88. 264
      spec/services/imports/user_import_service_spec.rb
  89. 8
      spec/support/bulk_upload/lettings_log_to_csv.rb

8
app/models/lettings_log.rb

@ -128,6 +128,14 @@ class LettingsLog < Log
SUFFIX_FROM_PERIOD = { 2 => "every 2 weeks", 3 => "every 4 weeks", 4 => "every month" }.freeze
RETIREMENT_AGES = { "M" => 67, "F" => 60, "X" => 67 }.freeze
DUPLICATE_LOG_ATTRIBUTES = %w[owning_organisation_id tenancycode startdate age1_known age1 sex1 ecstat1 tcharge household_charge chcharge].freeze
RENT_TYPE = {
social_rent: 0,
affordable_rent: 1,
london_affordable_rent: 2,
rent_to_buy: 3,
london_living_rent: 4,
other_intermediate_rent_product: 5,
}.freeze
def form
FormHandler.instance.get_form(form_name) || FormHandler.instance.current_lettings_form

12
app/services/bulk_upload/lettings/year2022/row_parser.rb

@ -1017,21 +1017,21 @@ private
def rent_type
case renttype
when :social
Imports::LettingsLogsImportService::RENT_TYPE[:social_rent]
LettingsLog::RENT_TYPE[:social_rent]
when :affordable
if field_129 == 1
Imports::LettingsLogsImportService::RENT_TYPE[:london_affordable_rent]
LettingsLog::RENT_TYPE[:london_affordable_rent]
else
Imports::LettingsLogsImportService::RENT_TYPE[:affordable_rent]
LettingsLog::RENT_TYPE[:affordable_rent]
end
when :intermediate
case field_130
when 1
Imports::LettingsLogsImportService::RENT_TYPE[:rent_to_buy]
LettingsLog::RENT_TYPE[:rent_to_buy]
when 2
Imports::LettingsLogsImportService::RENT_TYPE[:london_living_rent]
LettingsLog::RENT_TYPE[:london_living_rent]
when 3
Imports::LettingsLogsImportService::RENT_TYPE[:other_intermediate_rent_product]
LettingsLog::RENT_TYPE[:other_intermediate_rent_product]
end
end
end

12
app/services/bulk_upload/lettings/year2023/row_parser.rb

@ -1318,21 +1318,21 @@ private
def rent_type
case renttype
when :social
Imports::LettingsLogsImportService::RENT_TYPE[:social_rent]
LettingsLog::RENT_TYPE[:social_rent]
when :affordable
if field_10 == 1
Imports::LettingsLogsImportService::RENT_TYPE[:london_affordable_rent]
LettingsLog::RENT_TYPE[:london_affordable_rent]
else
Imports::LettingsLogsImportService::RENT_TYPE[:affordable_rent]
LettingsLog::RENT_TYPE[:affordable_rent]
end
when :intermediate
case field_11
when 1
Imports::LettingsLogsImportService::RENT_TYPE[:rent_to_buy]
LettingsLog::RENT_TYPE[:rent_to_buy]
when 2
Imports::LettingsLogsImportService::RENT_TYPE[:london_living_rent]
LettingsLog::RENT_TYPE[:london_living_rent]
when 3
Imports::LettingsLogsImportService::RENT_TYPE[:other_intermediate_rent_product]
LettingsLog::RENT_TYPE[:other_intermediate_rent_product]
end
end
end

61
app/services/imports/data_protection_confirmation_import_service.rb

@ -1,61 +0,0 @@
module Imports
class DataProtectionConfirmationImportService < ImportService
def create_data_protection_confirmations(folder)
import_from(folder, :create_data_protection_confirmation)
end
private
def create_data_protection_confirmation(xml_document)
org = Organisation.find_by(old_org_id: record_field_value(xml_document, "institution"))
return log_org_must_exist if org.blank?
return log_dpc_already_present(org) if org.data_protection_confirmed?
dp_officer = User.find_by(
name: record_field_value(xml_document, "dp-user"),
organisation: org,
is_dpo: true,
)
if dp_officer.blank?
dp_officer = User.new(
name: record_field_value(xml_document, "dp-user"),
organisation: org,
is_dpo: true,
encrypted_password: SecureRandom.hex(10),
email: SecureRandom.uuid,
confirmed_at: Time.zone.now,
active: false,
)
dp_officer.save!(validate: false)
end
DataProtectionConfirmation.create!(
organisation: org,
confirmed: record_field_value(xml_document, "data-protection").casecmp("true").zero?,
data_protection_officer: dp_officer,
old_id: record_field_value(xml_document, "id"),
old_org_id: record_field_value(xml_document, "institution"),
signed_at: record_field_value(xml_document, "change-date").to_time(:utc),
organisation_name: org.name,
organisation_address: org.address_row,
organisation_phone_number: org.phone,
data_protection_officer_email: dp_officer.email,
data_protection_officer_name: dp_officer.name,
)
end
def record_field_value(xml_document, field)
field_value(xml_document, "dataprotect", field)
end
def log_dpc_already_present(org)
@logger.warn("Data protection confirmation for #{org.name} with id #{org.id} is already present, skipping.")
end
def log_org_must_exist
@logger.error("Organisation must exist")
end
end
end

152
app/services/imports/import_report_service.rb

@ -1,152 +0,0 @@
module Imports
class ImportReportService
def initialize(storage_service, institutions_csv, logger = Rails.logger)
@storage_service = storage_service
@logger = logger
@institutions_csv = institutions_csv
end
BYTE_ORDER_MARK = "\uFEFF".freeze # Required to ensure Excel always reads CSV as UTF-8
def create_reports(report_suffix)
generate_missing_data_coordinators_report(report_suffix)
generate_logs_report(report_suffix)
generate_unassigned_logs_report(report_suffix)
end
def generate_missing_data_coordinators_report(report_suffix)
report_csv = "Organisation ID,Old Organisation ID,Organisation Name\n"
organisations = @institutions_csv.map { |row| Organisation.find_by(name: row[0]) }.compact
organisations.each do |organisation|
if organisation.users.none? { |user| user.data_coordinator? && user.active? }
report_csv += "#{organisation.id},#{organisation.old_visible_id},#{organisation.name}\n"
end
end
report_name = "OrganisationsWithoutDataCoordinators_#{report_suffix}"
@storage_service.write_file(report_name, BYTE_ORDER_MARK + report_csv)
@logger.info("Missing data coordinators report available in s3 import bucket at #{report_name}")
end
def generate_logs_report(report_suffix)
Rails.logger.info("Generating migrated logs report")
rep = CSV.generate do |report|
headers = ["Institution name", "Id", "Old Completed lettings logs", "Old In progress lettings logs", "Old Completed sales logs", "Old In progress sales logs", "New Completed lettings logs", "New In Progress lettings logs", "New Completed sales logs", "New In Progress sales logs"]
report << headers
@institutions_csv.each do |row|
name = row[0]
organisation = Organisation.find_by(name:)
next unless organisation
completed_sales_logs = organisation.owned_sales_logs.imported.where(status: "completed").count
in_progress_sales_logs = organisation.owned_sales_logs.imported.where(status: "in_progress").count
completed_lettings_logs = organisation.owned_lettings_logs.imported.where(status: "completed").count
in_progress_lettings_logs = organisation.owned_lettings_logs.imported.where(status: "in_progress").count
report << row.push(completed_lettings_logs, in_progress_lettings_logs, completed_sales_logs, in_progress_sales_logs)
end
end
report_name = "MigratedLogsReport_#{report_suffix}"
@storage_service.write_file(report_name, BYTE_ORDER_MARK + rep)
@logger.info("Logs report available in s3 import bucket at #{report_name}")
end
def generate_unassigned_logs_report(report_suffix)
Rails.logger.info("Generating unassigned logs report")
rep = CSV.generate do |report|
headers = ["Owning Organisation ID", "Old Owning Organisation ID", "Managing Organisation ID", "Old Managing Organisation ID", "Log ID", "Old Log ID", "Tenancy code", "Purchaser code"]
report << headers
@institutions_csv.each do |row|
name = row[0]
organisation = Organisation.find_by(name:)
next unless organisation
unassigned_user = organisation.users.find_by(name: "Unassigned")
next unless unassigned_user
organisation.owned_lettings_logs.imported.where(created_by: unassigned_user).each do |lettings_log|
report << [organisation.id, organisation.old_org_id, lettings_log.managing_organisation.id, lettings_log.managing_organisation.old_org_id, lettings_log.id, lettings_log.old_id, lettings_log.tenancycode, nil]
end
organisation.owned_sales_logs.imported.where(created_by: unassigned_user).each do |sales_log|
report << [organisation.id, organisation.old_org_id, nil, nil, sales_log.id, sales_log.old_id, nil, sales_log.purchid]
end
end
end
report_name = "UnassignedLogsReport_#{report_suffix}"
@storage_service.write_file(report_name, BYTE_ORDER_MARK + rep)
@logger.info("Unassigned logs report available in s3 import bucket at #{report_name}")
end
def generate_missing_answers_report(report_suffix)
create_missing_answers_report(report_suffix, LettingsLog)
create_missing_answers_report(report_suffix, SalesLog)
end
def create_missing_answers_report(report_suffix, log_class)
class_name = log_class.name.underscore.humanize
Rails.logger.info("Generating missing imported #{class_name}s answers report")
unanswered_question_counts, missing_answers_example_sets = process_missing_answers(log_class)
report_name = "MissingAnswersReport#{log_class.name}_#{report_suffix}.csv"
@storage_service.write_file(report_name, BYTE_ORDER_MARK + missing_answers_report(unanswered_question_counts))
examples_report_name = "MissingAnswersExamples#{log_class.name}_#{report_suffix}.csv"
@storage_service.write_file(examples_report_name, BYTE_ORDER_MARK + missing_answers_examples(missing_answers_example_sets))
@logger.info("Missing #{class_name}s answers report available in s3 import bucket at #{report_name}")
end
def process_missing_answers(log_class)
unanswered_question_counts = {}
missing_answers_example_sets = {}
log_class.where.not(old_id: nil).where(status: "in_progress").each do |log|
applicable_questions = log.form.subsections.map { |s| s.applicable_questions(log).select { |q| q.enabled?(log) } }.flatten
unanswered_questions = (applicable_questions.filter { |q| q.unanswered?(log) }.map(&:id) - log.optional_fields).join(", ")
if unanswered_question_counts[unanswered_questions].present?
unanswered_question_counts[unanswered_questions] += 1
missing_answers_example_sets[unanswered_questions] << { id: log.id, old_form_id: log.old_form_id, old_id: log.old_id, owning_organisation_id: log.owning_organisation_id } unless unanswered_question_counts[unanswered_questions] > 10
else
unanswered_question_counts[unanswered_questions] = 1
missing_answers_example_sets[unanswered_questions] = [{ id: log.id, old_form_id: log.old_form_id, old_id: log.old_id, owning_organisation_id: log.owning_organisation_id }]
end
end
[unanswered_question_counts, missing_answers_example_sets]
end
def missing_answers_report(unanswered_question_counts)
CSV.generate do |report|
headers = ["Missing answers", "Total number of affected logs"]
report << headers
unanswered_question_counts.each do |missing_answers, count|
report << [missing_answers, count]
end
end
end
def missing_answers_examples(missing_answers_example_sets)
CSV.generate do |report|
headers = ["Missing answers", "Organisation ID", "Log ID", "Old Form ID", "Old Log ID"]
report << headers
missing_answers_example_sets.each do |missing_answers, examples|
examples.each do |example|
report << [missing_answers, example[:owning_organisation_id], example[:id], example[:old_form_id], example[:old_id]]
end
end
end
end
end
end

51
app/services/imports/import_service.rb

@ -1,51 +0,0 @@
module Imports
class ImportService
attr_accessor :allow_updates
private
def initialize(storage_service, logger = Rails.logger, allow_updates: false)
@storage_service = storage_service
@logger = logger
@logs_with_discrepancies = []
@allow_updates = allow_updates
end
def import_from(folder, create_method)
filenames = @storage_service.list_files(folder)
filenames.each do |filename|
file_io = @storage_service.get_file_io(filename)
xml_document = Nokogiri::XML(file_io)
send(create_method, xml_document)
rescue StandardError => e
@logger.error "#{e.class} in #{filename}: #{e.message}. Caller: #{e.backtrace.first}"
end
end
def dataprotect_xml
data_protect_filename = @storage_service.list_files("dataprotect").first
file_io = @storage_service.get_file_io(data_protect_filename)
Nokogiri::XML(file_io)
end
def field_value(xml_document, namespace, field, *args)
if namespace.present?
xml_document.at_xpath("//#{namespace}:#{field}", *args)&.text
else
xml_document.at_xpath("//dclg:#{field}", *args + [{ "dclg" => "dclg:institution" }])&.text
end
end
def meta_field_value(xml_document, field)
field_value(xml_document, "meta", field, { "meta" => "http://data.gov.uk/core/metadata" })
end
def overridden?(xml_document, namespace, field)
xml_document.at_xpath("//#{namespace}:#{field}").attributes["override-field"].value
end
def to_boolean(input_string)
input_string == "true"
end
end
end

482
app/services/imports/lettings_logs_field_import_service.rb

@ -1,482 +0,0 @@
module Imports
class LettingsLogsFieldImportService < LogsImportService
def update_field(field, folder)
case field
when "tenancycode"
import_from(folder, :update_tenant_code)
when "major_repairs"
import_from(folder, :update_major_repairs)
when "lettings_allocation"
import_from(folder, :update_lettings_allocation)
when "offered"
import_from(folder, :update_offered)
when "creation_method"
import_from(folder, :update_creation_method)
when "address"
import_from(folder, :update_address)
when "reason"
import_from(folder, :update_reason)
when "homeless"
import_from(folder, :update_homelessness)
when "created_by"
import_from(folder, :update_created_by)
when "sex_and_relat"
import_from(folder, :update_sex_and_relat)
when "general_needs_referral"
import_from(folder, :update_general_needs_referral)
when "person_details"
import_from(folder, :update_person_details)
when "childrens_care_referral"
import_from(folder, :update_childrens_care_referral)
when "old_form_id"
import_from(folder, :update_old_form_id)
when "postcode_full"
import_from(folder, :update_postcode_full)
else
raise "Updating #{field} is not supported by the field import service"
end
end
private
def update_offered(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
if record.offered.present?
@logger.info("lettings log #{record.id} has a value for offered, skipping update")
else
offered = safe_string_as_integer(xml_doc, "Q20")
record.update!(offered:)
@logger.info("lettings log #{record.id}'s offered value has been set to #{offered}")
end
else
@logger.warn("lettings log with old id #{old_id} not found")
end
end
def update_creation_method(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
log = LettingsLog.find_by(old_id:)
return @logger.warn "lettings log with old id #{old_id} not found" unless log
upload_id = meta_field_value(xml_doc, "upload-id")
if upload_id.nil?
@logger.info "lettings log with old id #{old_id} entered manually, no need for update"
elsif log.creation_method_bulk_upload?
@logger.info "lettings log #{log.id} creation method already set to bulk upload, no need for update"
else
log.creation_method_bulk_upload!
@logger.info "lettings log #{log.id} creation method set to bulk upload"
end
end
def update_lettings_allocation(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
previous_status = meta_field_value(xml_doc, "status")
record = LettingsLog.find_by(old_id:)
if record.present? && previous_status.include?("submitted")
cbl = unsafe_string_as_integer(xml_doc, "Q15CBL")
chr = unsafe_string_as_integer(xml_doc, "Q15CHR")
cap = unsafe_string_as_integer(xml_doc, "Q15CAP")
if cbl == 2 && record.cbl == 1
record.update!(cbl: 0)
@logger.info("lettings log #{record.id}'s cbl value has been updated'")
end
if chr == 2 && record.chr == 1
record.update!(chr: 0)
@logger.info("lettings log #{record.id}'s chr value has been updated'")
end
if cap == 2 && record.cap == 1
record.update!(cap: 0)
@logger.info("lettings log #{record.id}'s cap value has been updated'")
end
if cbl == 2 && chr == 2 && cap == 2 && record.letting_allocation_unknown.nil?
record.update!(letting_allocation_unknown: 1)
@logger.info("lettings log #{record.id}'s letting_allocation_unknown value has been updated'")
end
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
def update_major_repairs(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
previous_status = meta_field_value(xml_doc, "status")
major_repairs_date = compose_date(xml_doc, "MRCDAY", "MRCMONTH", "MRCYEAR")
major_repairs = if major_repairs_date.present? && previous_status.include?("submitted")
1
elsif previous_status.include?("submitted")
0
end
if major_repairs.present? && record.majorrepairs.nil? && record.status != "completed"
record.update!(mrcdate: major_repairs_date, majorrepairs: major_repairs)
@logger.info("lettings log #{record.id}'s major repair value has been updated'")
elsif record.majorrepairs.present?
@logger.info("lettings log #{record.id} has a value for major repairs, skipping update")
end
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
def update_tenant_code(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
tenant_code = string_or_nil(xml_doc, "_2bTenCode")
if tenant_code.present? && record.tenancycode.blank?
record.update!(tenancycode: tenant_code)
else
@logger.info("lettings log #{record.id} has a value for tenancycode, skipping update")
end
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
def update_address(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.info("lettings log #{record.id} is from previous collection year, skipping") if record.collection_start_year < 2023
if record.present?
if string_or_nil(xml_doc, "AddressLine1").present? && string_or_nil(xml_doc, "TownCity").present?
record.la = string_or_nil(xml_doc, "Q28ONS")
record.postcode_full = compose_postcode(xml_doc, "POSTCODE", "POSTCOD2")
record.postcode_known = postcode_known(record)
record.address_line1 = string_or_nil(xml_doc, "AddressLine1")
record.address_line2 = string_or_nil(xml_doc, "AddressLine2")
record.town_or_city = string_or_nil(xml_doc, "TownCity")
record.county = string_or_nil(xml_doc, "County")
record.uprn = nil
record.uprn_known = 0
record.uprn_confirmed = 0
record.values_updated_at = Time.zone.now
record.save!
@logger.info("lettings log #{record.id} address_line1 value has been set to #{record.address_line1}")
@logger.info("lettings log #{record.id} address_line2 value has been set to #{record.address_line2}")
@logger.info("lettings log #{record.id} town_or_city value has been set to #{record.town_or_city}")
@logger.info("lettings log #{record.id} county value has been set to #{record.county}")
@logger.info("lettings log #{record.id} postcode_full value has been set to #{record.postcode_full}")
else
@logger.info("lettings log #{record.id} is missing either or both of address_line1 and town or city, skipping")
end
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
def postcode_known(record)
if record.postcode_full.nil?
record.la.nil? ? nil : 0 # Assumes we selected No in the form since the LA is present
else
1
end
end
def update_reason(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
if record.reason.present?
@logger.info("lettings log #{record.id} has a value for reason, skipping update")
else
reason = unsafe_string_as_integer(xml_doc, "Q9a")
reasonother = string_or_nil(xml_doc, "Q9aa")
if reason == 20 && reasonother.blank?
@logger.info("lettings log #{record.id}'s reason is other but other reason is not provided, skipping update")
else
record.update!(reason:, reasonother:, values_updated_at: Time.zone.now)
@logger.info("lettings log #{record.id}'s reason value has been set to #{reason}")
@logger.info("lettings log #{record.id}'s reasonother value has been set to #{reasonother}") if record.reasonother.present?
end
end
else
@logger.warn("lettings log with old id #{old_id} not found")
end
end
def update_homelessness(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
return @logger.info("lettings log #{record.id} has a value for homeless and rp_homeless, skipping update") if record.rp_homeless == 1 && record.homeless.present?
return @logger.info("lettings log #{record.id} has a value for homeless and reasonpref is not yes, skipping update") if record.reasonpref != 1 && record.homeless.present?
return @logger.info("lettings log #{record.id} reimport values are not homeless - 1 (no) and rp_homeless - yes, skipping update") if unsafe_string_as_integer(xml_doc, "Q14b1").blank? || unsafe_string_as_integer(xml_doc, "Q13") != 1
if record.rp_homeless != 1 && record.reasonpref == 1
record.rp_homeless = 1
@logger.info("updating lettings log #{record.id}'s rp_homeless value to 1")
end
if record.homeless.blank?
record.homeless = 1
@logger.info("updating lettings log #{record.id}'s homeless value to 1")
end
record.values_updated_at = Time.zone.now
record.save!
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
# deletes and recreates the entire record if created_by is missing
def update_created_by(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.warn("lettings log with old id #{old_id} not found") unless record
return @logger.info("lettings log #{record.id} has created_by value, skipping update") if record.created_by.present?
record.destroy!
@logger.info("lettings log #{record.id} has been deleted")
log_import_service = Imports::LettingsLogsImportService.new(nil, @logger)
log_import_service.send(:create_log, xml_doc)
@logger.info("lettings log \"#{record.old_id}\" has been reimported with id #{record.id}")
end
def update_sex_and_relat(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.warn("lettings log with old id #{old_id} not found") unless record
return @logger.info("lettings log #{record.id} has no hhmemb value, skipping update") if record.hhmemb.blank?
if record.sex1.present?
@logger.info("lettings log #{record.id} has value for sex1, skipping person")
else
record.sex1 = sex(xml_doc, 1)
@logger.info("lettings log #{record.id}'s sex1 value has been set to #{record.sex1}")
end
(2..record.hhmemb).each do |i|
next @logger.info("lettings log #{record.id} has values for sex#{i} and relat#{i}, skipping person") if record["sex#{i}"] && record["relat#{i}"]
next @logger.info("lettings log #{record.id} has value 'no' for details_known_#{i}, skipping person") if record.details_not_known_for_person?(i)
if record["sex#{i}"].blank?
record["sex#{i}"] = sex(xml_doc, i)
@logger.info("lettings log #{record.id}'s sex#{i} value has been set to #{record["sex#{i}"]}")
end
if record["relat#{i}"].blank?
record["relat#{i}"] = relat(xml_doc, i)
@logger.info("lettings log #{record.id}'s relat#{i} value has been set to #{record["relat#{i}"]}")
end
end
if record.changed?
record.values_updated_at = Time.zone.now
record.save!
end
end
def update_general_needs_referral(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.warn("lettings log with old id #{old_id} not found") unless record
return @logger.info("lettings log #{record.id} has a value for referral, skipping update") if record.referral.present?
return @logger.info("lettings log #{record.id} is a supported housing log, skipping update") if record.needstype == 2
return @logger.info("lettings log #{record.id}'s owning organisation's provider type is LA, skipping update") if record.owning_organisation.provider_type == "LA"
return @logger.info("lettings log #{record.id} reimport referral value is not 4, skipping update") if unsafe_string_as_integer(xml_doc, "Q16") != 4
record.update!(referral: 4, referral_value_check: 0, values_updated_at: Time.zone.now)
@logger.info("lettings log #{record.id}'s referral value has been set to 4")
end
def update_person_details(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.warn("lettings log with old id #{old_id} not found") unless record
return @logger.info("lettings log #{record.id} has no hhmemb, skipping update") unless record.hhmemb
if (2..record.hhmemb).all? { |person_index| record.has_any_person_details?(person_index) || record.details_not_known_for_person?(person_index) }
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
person_index = 2
next_person_index = person_index + 1
while person_exists_on_the_log?(record, person_index)
if person_exists_on_the_log?(record, next_person_index)
if record.has_any_person_details?(person_index) || record.details_not_known_for_person?(person_index)
@logger.info("lettings log #{record.id} has details for person #{person_index}, skipping person")
person_index += 1
next_person_index += 1
next
end
if !record.has_any_person_details?(next_person_index) && !record.details_not_known_for_person?(next_person_index)
next_person_index += 1
next
end
move_person_details(record, person_index, next_person_index)
else
reimport_person_details(record, xml_doc, person_index, next_person_index)
end
person_index += 1
next_person_index += 1
end
record.values_updated_at = Time.zone.now
record.save!
end
def age_known(xml_doc, person_index)
age_refused = string_or_nil(xml_doc, "P#{person_index}AR")
if age_refused.present?
if age_refused.casecmp?("AGE_REFUSED") || age_refused.casecmp?("No")
return 1 # No
else
return 0 # Yes
end
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
def move_person_details(record, person_index, next_person_index)
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")
end
def reimport_person_details(record, xml_doc, person_index, next_person_index)
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")
end
def person_exists_on_the_log?(record, person_index)
person_index <= record.hhmemb
end
def update_childrens_care_referral(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.warn("lettings log with old id #{old_id} not found") unless record
return @logger.info("lettings log #{record.id} has a value for referral, skipping update") if record.referral.present?
return @logger.info("lettings log #{record.id} reimport referral value is not 17, skipping update") if unsafe_string_as_integer(xml_doc, "Q16") != 17
record.update!(referral: 17, values_updated_at: Time.zone.now)
@logger.info("lettings log #{record.id}'s referral value has been set to 17")
end
def update_old_form_id(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
if record.present?
if record.old_form_id.present?
@logger.info("lettings log #{record.id} has a value for old_form_id, skipping update")
else
old_form_id = safe_string_as_integer(xml_doc, "FORM")
record.update!(old_form_id:)
@logger.info("lettings log #{record.id}'s old_form_id value has been set to #{old_form_id}")
end
else
@logger.warn("lettings log with old id #{old_id} not found")
end
end
def update_postcode_full(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = LettingsLog.find_by(old_id:)
return @logger.info("lettings log #{record.id} is not from 2022/23 collection period, skipping update") if record.collection_start_year != 2022
return @logger.warn("Could not find record matching legacy ID #{old_id}") if record.blank?
return @logger.info("lettings log #{record.id} has a value for postcode_full, skipping update") if record.postcode_full.present?
record.postcode_full = compose_postcode(xml_doc, "POSTCODE", "POSTCOD2")
if record.postcode_full.present?
record.postcode_known = postcode_known(record)
record.values_updated_at = Time.zone.now
if record.save
@logger.info("lettings log #{record.id} postcode_full value has been set to #{record.postcode_full}")
else
@logger.error("lettings log #{record.id} postcode_full value has not been set. Errors: #{record.errors.full_messages.join(', ')}")
end
else
@logger.info("lettings log #{record.id} is missing postcode_full, skipping update")
end
end
end
end

698
app/services/imports/lettings_logs_import_service.rb

@ -1,698 +0,0 @@
module Imports
class LettingsLogsImportService < LogsImportService
def initialize(storage_service, logger = Rails.logger, allow_updates: false)
@logs_with_discrepancies = Set.new
@logs_overridden = Set.new
super
end
def create_logs(folder)
import_from(folder, :create_log)
end
private
FORM_NAME_INDEX = {
start_year: 0,
rent_type: 2,
needs_type: 3,
}.freeze
GN_SH = {
general_needs: 1,
supported_housing: 2,
}.freeze
SR_AR_IR = {
social_rent: 1,
affordable_rent: 2,
intermediate_rent: 3,
}.freeze
# For providertype, values are reversed!!!
PRP_LA = {
private_registered_provider: 1,
local_authority: 2,
}.freeze
IRPRODUCT = {
rent_to_buy: 1,
london_living_rent: 2,
other_intermediate_rent_product: 3,
}.freeze
# These must match our form
RENT_TYPE = {
social_rent: 0,
affordable_rent: 1,
london_affordable_rent: 2,
rent_to_buy: 3,
london_living_rent: 4,
other_intermediate_rent_product: 5,
}.freeze
def create_log(xml_doc)
return if meta_field_value(xml_doc, "form-name").include?("Sales")
attributes = {}
previous_status = meta_field_value(xml_doc, "status")
# Required fields for status complete or logic to work
# Note: order matters when we derive from previous values (attributes parameter)
attributes["startdate"] = compose_date(xml_doc, "DAY", "MONTH", "YEAR")
attributes["owning_organisation_id"] = find_organisation_id(xml_doc, "owner-institution-id")
attributes["managing_organisation_id"] = find_organisation_id(xml_doc, "managing-institution-id")
attributes["creation_method"] = creation_method(xml_doc)
attributes["joint"] = unsafe_string_as_integer(xml_doc, "joint")
attributes["startertenancy"] = unsafe_string_as_integer(xml_doc, "_2a")
attributes["tenancy"] = unsafe_string_as_integer(xml_doc, "Q2b")
attributes["tenancycode"] = string_or_nil(xml_doc, "_2bTenCode")
attributes["tenancyother"] = string_or_nil(xml_doc, "Q2ba")
attributes["tenancylength"] = safe_string_as_integer(xml_doc, "_2cYears")
attributes["needstype"] = needs_type(xml_doc)
attributes["lar"] = london_affordable_rent(xml_doc)
attributes["irproduct"] = unsafe_string_as_integer(xml_doc, "IRProduct")
attributes["irproduct_other"] = string_or_nil(xml_doc, "IRProductOther")
attributes["rent_type"] = rent_type(xml_doc, attributes["lar"], attributes["irproduct"])
attributes["hhmemb"] = household_members(xml_doc, previous_status)
people_indexes = people_with_details_ids(xml_doc)
available_people_indexes = people_indexes + (people_indexes.max + 1..8).to_a
(1..8).each do |index|
person_index = available_people_indexes[index - 1]
attributes["age#{index}"] = safe_string_as_integer(xml_doc, "P#{person_index}Age")
attributes["age#{index}_known"] = age_known(xml_doc, index, person_index, attributes["hhmemb"])
attributes["sex#{index}"] = sex(xml_doc, person_index)
attributes["ecstat#{index}"] = unsafe_string_as_integer(xml_doc, "P#{person_index}Eco")
end
(2..8).each do |index|
person_index = available_people_indexes[index - 1]
attributes["relat#{index}"] = relat(xml_doc, person_index)
attributes["details_known_#{index}"] = details_known(index, attributes)
# Trips validation
if attributes["age#{index}"].present? && attributes["age#{index}"] < 16 && attributes["relat#{index}"].present? && attributes["relat#{index}"] != "C" && attributes["relat#{index}"] != "R"
attributes["age#{index}"] = nil
attributes["relat#{index}"] = nil
end
end
attributes["ethnic"] = unsafe_string_as_integer(xml_doc, "P1Eth")
attributes["ethnic_group"] = ethnic_group(attributes["ethnic"])
attributes["national"] = unsafe_string_as_integer(xml_doc, "P1Nat")
attributes["preg_occ"] = unsafe_string_as_integer(xml_doc, "Preg")
attributes["armedforces"] = unsafe_string_as_integer(xml_doc, "ArmedF")
attributes["leftreg"] = unsafe_string_as_integer(xml_doc, "LeftAF")
attributes["reservist"] = unsafe_string_as_integer(xml_doc, "Inj")
attributes["hb"] = unsafe_string_as_integer(xml_doc, "Q6Ben")
attributes["benefits"] = unsafe_string_as_integer(xml_doc, "Q7Ben")
attributes["earnings"] = safe_string_as_decimal(xml_doc, "Q8Money")&.round
attributes["net_income_known"] = net_income_known(xml_doc, attributes["earnings"])
attributes["incfreq"] = unsafe_string_as_integer(xml_doc, "Q8a")
attributes["reason"] = unsafe_string_as_integer(xml_doc, "Q9a")
attributes["reasonother"] = string_or_nil(xml_doc, "Q9aa")
attributes["underoccupation_benefitcap"] = unsafe_string_as_integer(xml_doc, "_9b")
%w[a b c f g h].each do |letter|
attributes["housingneeds_#{letter}"] = housing_needs(xml_doc, letter)
end
attributes["housingneeds"] = 1 if [attributes["housingneeds_a"], attributes["housingneeds_b"], attributes["housingneeds_c"], attributes["housingneeds_f"]].any? { |housingneed| housingneed == 1 }
attributes["housingneeds"] = 2 if attributes["housingneeds_g"] == 1
attributes["housingneeds"] = 3 if attributes["housingneeds_h"] == 1
attributes["housingneeds_type"] = 0 if attributes["housingneeds_a"] == 1
attributes["housingneeds_type"] = 1 if attributes["housingneeds_b"] == 1
attributes["housingneeds_type"] = 2 if attributes["housingneeds_c"] == 1
attributes["housingneeds_type"] = 3 if attributes["housingneeds_f"] == 1 && [attributes["housingneeds_a"], attributes["housingneeds_b"], attributes["housingneeds_c"]].all? { |housingneed| housingneed != 1 }
attributes["housingneeds_other"] = attributes["housingneeds_f"] == 1 ? 1 : 0
attributes["illness"] = unsafe_string_as_integer(xml_doc, "Q10ia")
(1..10).each do |index|
attributes["illness_type_#{index}"] = illness_type(xml_doc, index, attributes["illness"])
end
attributes["prevten"] = unsafe_string_as_integer(xml_doc, "Q11")
attributes["prevloc"] = string_or_nil(xml_doc, "Q12aONS")
attributes["ppostcode_full"] = compose_postcode(xml_doc, "PPOSTC1", "PPOSTC2")
attributes["ppcodenk"] = previous_postcode_known(xml_doc, attributes["ppostcode_full"], attributes["prevloc"])
attributes["layear"] = unsafe_string_as_integer(xml_doc, "Q12c")
attributes["waityear"] = unsafe_string_as_integer(xml_doc, "Q12d")
attributes["homeless"] = unsafe_string_as_integer(xml_doc, "Q13")
attributes["reasonpref"] = unsafe_string_as_integer(xml_doc, "Q14a")
attributes["rp_homeless"] = unsafe_string_as_integer(xml_doc, "Q14b1").present? ? 1 : nil
attributes["rp_insan_unsat"] = unsafe_string_as_integer(xml_doc, "Q14b2").present? ? 1 : nil
attributes["rp_medwel"] = unsafe_string_as_integer(xml_doc, "Q14b3").present? ? 1 : nil
attributes["rp_hardship"] = unsafe_string_as_integer(xml_doc, "Q14b4").present? ? 1 : nil
attributes["rp_dontknow"] = unsafe_string_as_integer(xml_doc, "Q14b5").present? ? 1 : nil
attributes["cbl"] = allocation_system(unsafe_string_as_integer(xml_doc, "Q15CBL"))
attributes["chr"] = allocation_system(unsafe_string_as_integer(xml_doc, "Q15CHR"))
attributes["cap"] = allocation_system(unsafe_string_as_integer(xml_doc, "Q15CAP"))
attributes["letting_allocation_unknown"] = allocation_system_unknown(attributes["cbl"], attributes["chr"], attributes["cap"])
attributes["referral"] = unsafe_string_as_integer(xml_doc, "Q16")
attributes["period"] = unsafe_string_as_integer(xml_doc, "Q17")
attributes["brent"] = safe_string_as_decimal(xml_doc, "Q18ai")
attributes["scharge"] = safe_string_as_decimal(xml_doc, "Q18aii")
attributes["pscharge"] = safe_string_as_decimal(xml_doc, "Q18aiii")
attributes["supcharg"] = safe_string_as_decimal(xml_doc, "Q18aiv")
attributes["tcharge"] = safe_string_as_decimal(xml_doc, "Q18av")
attributes["hbrentshortfall"] = unsafe_string_as_integer(xml_doc, "Q18d")
attributes["tshortfall"] = safe_string_as_decimal(xml_doc, "Q18dyes")
attributes["tshortfall_known"] = tshortfall_known?(xml_doc, attributes)
attributes["voiddate"] = compose_date(xml_doc, "VDAY", "VMONTH", "VYEAR")
attributes["mrcdate"] = compose_date(xml_doc, "MRCDAY", "MRCMONTH", "MRCYEAR")
attributes["majorrepairs"] = if attributes["mrcdate"].present? && previous_status.include?("submitted")
1
elsif previous_status.include?("submitted")
0
end
attributes["offered"] = safe_string_as_decimal(xml_doc, "Q20")
attributes["propcode"] = string_or_nil(xml_doc, "Q21a")
attributes["beds"] = safe_string_as_integer(xml_doc, "Q22")
attributes["unittype_gn"] = unsafe_string_as_integer(xml_doc, "Q23")
attributes["builtype"] = unsafe_string_as_integer(xml_doc, "Q24")
attributes["wchair"] = unsafe_string_as_integer(xml_doc, "Q25")
attributes["unitletas"] = unsafe_string_as_integer(xml_doc, "Q26")
attributes["rsnvac"] = unsafe_string_as_integer(xml_doc, "Q27")
attributes["renewal"] = renewal(attributes["rsnvac"])
attributes["la"] = string_or_nil(xml_doc, "Q28ONS")
attributes["postcode_full"] = compose_postcode(xml_doc, "POSTCODE", "POSTCOD2")
attributes["postcode_known"] = postcode_known(attributes)
# Not specific to our form but required for consistency (present in import)
attributes["old_form_id"] = safe_string_as_integer(xml_doc, "FORM")
attributes["created_at"] = Time.zone.parse(meta_field_value(xml_doc, "created-date"))
attributes["updated_at"] = Time.zone.parse(meta_field_value(xml_doc, "modified-date"))
attributes["old_id"] = meta_field_value(xml_doc, "document-id")
# Required for our form invalidated questions (not present in import)
attributes["previous_la_known"] = attributes["prevloc"].nil? ? 0 : 1
attributes["is_la_inferred"] = attributes["postcode_full"].present?
attributes["first_time_property_let_as_social_housing"] = first_time_let(attributes["rsnvac"])
attributes["declaration"] = declaration(xml_doc)
attributes["address_line1"] = string_or_nil(xml_doc, "AddressLine1")
attributes["address_line2"] = string_or_nil(xml_doc, "AddressLine2")
attributes["town_or_city"] = string_or_nil(xml_doc, "TownCity")
attributes["county"] = string_or_nil(xml_doc, "County")
attributes["uprn"] = address_given?(attributes) ? nil : string_or_nil(xml_doc, "UPRN")
attributes["uprn_known"] = attributes["uprn"].present? ? 1 : 0
attributes["uprn_confirmed"] = attributes["uprn"].present? ? 1 : 0
set_partial_charges_to_zero(attributes)
# Supported Housing fields
if attributes["needstype"] == GN_SH[:supported_housing]
location_old_visible_id = string_or_nil(xml_doc, "_1cschemecode")
scheme_old_visible_id = string_or_nil(xml_doc, "_1cmangroupcode")
schemes = Scheme.where(old_visible_id: scheme_old_visible_id, owning_organisation_id: attributes["owning_organisation_id"])
location = Location.find_by(old_visible_id: location_old_visible_id, scheme: schemes)
if location.present?
# Set the scheme via location, because the scheme old visible ID can be duplicated at import
attributes["location_id"] = location.id
attributes["scheme_id"] = location.scheme.id
attributes["sheltered"] = unsafe_string_as_integer(xml_doc, "Q1e")
attributes["chcharge"] = safe_string_as_decimal(xml_doc, "Q18b")
attributes["household_charge"] = household_charge(xml_doc)
attributes["is_carehome"] = is_carehome(location.scheme)
end
end
# Handles confidential schemes
if attributes["postcode_full"] == "******"
attributes["postcode_known"] = 0
attributes["postcode_full"] = nil
end
# Soft validations can become required answers, set them to yes by default
attributes["pregnancy_value_check"] = 0
attributes["major_repairs_date_value_check"] = 0
attributes["void_date_value_check"] = 0
attributes["retirement_value_check"] = 0
attributes["rent_value_check"] = 0
attributes["net_income_value_check"] = 0
attributes["carehome_charges_value_check"] = 0
attributes["referral_value_check"] = 0
attributes["scharge_value_check"] = 0
attributes["pscharge_value_check"] = 0
attributes["supcharg_value_check"] = 0
# Sets the log creator
owner_id = meta_field_value(xml_doc, "owner-user-id").strip
user = LegacyUser.find_by(old_user_id: owner_id)&.user
if owner_id.blank? || user.blank? || (user.organisation_id != attributes["managing_organisation_id"] && user.organisation_id != attributes["owning_organisation_id"])
if owner_id.blank?
@logger.error("Lettings log '#{attributes['old_id']}' does not have the owner id. Assigning log to 'Unassigned' user.")
elsif user.blank?
@logger.error("Lettings log '#{attributes['old_id']}' belongs to legacy user with owner-user-id: '#{owner_id}' which cannot be found. Assigning log to 'Unassigned' user.")
else
@logger.error("Lettings log '#{attributes['old_id']}' belongs to legacy user with owner-user-id: '#{owner_id}' which belongs to a different organisation. Assigning log to 'Unassigned' user.")
end
if User.find_by(name: "Unassigned", organisation_id: attributes["managing_organisation_id"])
user = User.find_by(name: "Unassigned", organisation_id: attributes["managing_organisation_id"])
else
user = User.new(
name: "Unassigned",
organisation_id: attributes["managing_organisation_id"],
is_dpo: false,
encrypted_password: SecureRandom.hex(10),
email: SecureRandom.uuid,
confirmed_at: Time.zone.now,
active: false,
)
user.save!(validate: false)
end
end
attributes["created_by"] = user
attributes["values_updated_at"] = Time.zone.now
apply_date_consistency!(attributes)
apply_household_consistency!(attributes)
create_organisation_relationship!(attributes)
lettings_log = save_lettings_log(attributes, previous_status)
compute_differences(lettings_log, attributes)
check_status_completed(lettings_log, previous_status) unless @logs_overridden.include?(lettings_log.old_id)
end
def save_lettings_log(attributes, previous_status)
lettings_log = LettingsLog.new(attributes)
begin
legacy_id = attributes["old_id"]
record = LettingsLog.find_by(old_id: legacy_id)
if record.present?
if allow_updates
attributes["updated_at"] = Time.zone.now
record.update!(attributes)
end
record
else
duplicate_logs = lettings_log.owning_organisation.owned_lettings_logs.not_imported.duplicate_logs(lettings_log)
if duplicate_logs.count.positive?
@logger.info("Duplicate log with id #{duplicate_logs.map(&:id).join(', ')} found for log #{lettings_log.old_id}, skipping log")
else
lettings_log.save!
end
lettings_log
end
rescue ActiveRecord::RecordInvalid => e
rescue_validation_or_raise(lettings_log, attributes, previous_status, e)
end
end
def rescue_validation_or_raise(lettings_log, attributes, previous_status, exception)
charges_attributes = %w[brent scharge pscharge supcharg tcharge]
# Blank out all invalid fields for in-progress logs
if %w[saved submitted-invalid].include?(previous_status)
lettings_log.errors.each do |error|
attributes.delete(error.attribute.to_s)
charges_attributes.each { |attribute| attributes.delete(attribute) } if error.attribute == :tcharge
end
@logs_overridden << lettings_log.old_id
return save_lettings_log(attributes, previous_status)
end
errors = {
%i[chcharge out_of_range] => %w[chcharge],
%i[referral internal_transfer_non_social_housing] => %w[referral],
%i[referral internal_transfer_fixed_or_lifetime] => %w[referral],
%i[tenancylength tenancylength_invalid] => %w[tenancylength],
%i[prevten over_25_foster_care] => %w[prevten age1],
%i[prevten non_temp_accommodation] => %w[prevten rsnvac],
%i[joint not_joint_tenancy] => %w[joint],
%i[offered outside_the_range] => %w[offered],
%i[offered not_integer] => %w[offered],
%i[earnings over_hard_max] => %w[ecstat1],
%i[tshortfall no_outstanding_charges] => %w[tshortfall hbrentshortfall],
%i[beds outside_the_range] => %w[beds],
%i[tcharge complete_1_of_3] => charges_attributes,
%i[scharge under_min] => charges_attributes,
%i[tshortfall must_be_positive] => %w[tshortfall tshortfall_known],
%i[referral referral_invalid] => %w[referral],
%i[pscharge outside_the_range] => charges_attributes,
%i[supcharg outside_the_range] => charges_attributes,
%i[scharge outside_the_range] => charges_attributes,
%i[location_id not_active] => %w[location_id scheme_id],
%i[tcharge under_10] => charges_attributes,
%i[brent over_hard_max] => charges_attributes,
%i[brent below_hard_min] => charges_attributes,
%i[period wrong_rent_period] => %w[period],
%i[layear renewal_just_moved] => %w[layear],
%i[voiddate after_mrcdate] => %w[voiddate mrcdate majorrepairs],
%i[tshortfall more_than_rent] => %w[tshortfall tshortfall_known],
%i[scheme_id no_completed_locations] => %w[scheme_id location_id],
%i[location_id incomplete] => %w[scheme_id location_id],
%i[beds one_three_bedroom_single_tenant_shared] => %w[beds],
}
(2..8).each do |person|
errors[[:"age#{person}", :outside_the_range]] = ["age#{person}", "age#{person}_known"]
end
errors.each do |(error, fields)|
next unless lettings_log.errors.of_kind?(*error)
fields.each do |field|
attributes.delete(field)
end
@logs_overridden << lettings_log.old_id
return save_lettings_log(attributes, previous_status)
end
if lettings_log.errors.of_kind?(:earnings, :under_hard_min)
@logs_overridden << lettings_log.old_id
attributes.delete("earnings")
attributes.delete("incfreq")
attributes["incref"] = 1
attributes["net_income_known"] = 2
return save_lettings_log(attributes, previous_status)
end
if lettings_log.errors.of_kind?(:uprn, :uprn_error)
@logs_overridden << lettings_log.old_id
attributes["uprn_known"] = 0
return save_lettings_log(attributes, previous_status)
end
@logger.error("Log #{lettings_log.old_id}: Failed to import")
lettings_log.errors.each do |error|
@logger.error("Validation error: Field #{error.attribute}:")
@logger.error("\tOwning Organisation: #{lettings_log.owning_organisation&.name}")
@logger.error("\tManaging Organisation: #{lettings_log.managing_organisation&.name}")
@logger.error("\tOld CORE ID: #{lettings_log.old_id}")
@logger.error("\tOld CORE: #{attributes[error.attribute.to_s]&.inspect}")
@logger.error("\tNew CORE: #{lettings_log.read_attribute(error.attribute)&.inspect}")
@logger.error("\tError message: #{error.type}")
end
raise exception
end
def compute_differences(lettings_log, attributes)
differences = []
attributes.each do |key, value|
lettings_log_value = lettings_log.send(key.to_sym)
next if fields_not_present_in_softwire_data.include?(key)
if value != lettings_log_value
differences.push("#{key} #{value.inspect} #{lettings_log_value.inspect}")
end
end
end
def fields_not_present_in_softwire_data
%w[majorrepairs illness_type_0 tshortfall_known pregnancy_value_check retirement_value_check rent_value_check net_income_value_check major_repairs_date_value_check void_date_value_check carehome_charges_value_check referral_value_check scharge_value_check pscharge_value_check supcharg_value_check housingneeds_type housingneeds_other created_by uprn_known uprn_confirmed]
end
def check_status_completed(lettings_log, previous_status)
if previous_status.include?("submitted") && lettings_log.status != "completed"
@logs_with_discrepancies << lettings_log.old_id
end
end
def get_form_name_component(xml_doc, index)
form_name = meta_field_value(xml_doc, "form-name")
form_type_components = form_name.split("-")
form_type_components[index]
end
def needs_type(xml_doc)
gn_sh = get_form_name_component(xml_doc, FORM_NAME_INDEX[:needs_type])
case gn_sh
when "GN"
GN_SH[:general_needs]
when "SH"
GN_SH[:supported_housing]
else
raise "Unknown needstype value: #{gn_sh}"
end
end
# This does not match renttype (CDS) which is derived by lettings log logic
def rent_type(xml_doc, lar, irproduct)
sr_ar_ir = get_form_name_component(xml_doc, FORM_NAME_INDEX[:rent_type])
case sr_ar_ir
when "SR"
RENT_TYPE[:social_rent]
when "AR"
if lar == 1
RENT_TYPE[:london_affordable_rent]
else
RENT_TYPE[:affordable_rent]
end
when "IR"
if irproduct == IRPRODUCT[:rent_to_buy]
RENT_TYPE[:rent_to_buy]
elsif irproduct == IRPRODUCT[:london_living_rent]
RENT_TYPE[:london_living_rent]
elsif irproduct == IRPRODUCT[:other_intermediate_rent_product]
RENT_TYPE[:other_intermediate_rent_product]
end
else
raise "Could not infer rent type with '#{sr_ar_ir}'"
end
end
def age_known(xml_doc, index, person_index, hhmemb)
return nil if hhmemb.present? && index > hhmemb
age_refused = string_or_nil(xml_doc, "P#{person_index}AR")
if age_refused.present?
if age_refused.casecmp?("AGE_REFUSED") || age_refused.casecmp?("No")
return 1 # No
else
return 0 # Yes
end
end
0
end
def details_known(index, attributes)
return nil if attributes["hhmemb"].nil? || index > attributes["hhmemb"]
if attributes["age#{index}_known"] == 1 &&
attributes["sex#{index}"] == "R" &&
attributes["relat#{index}"] == "R" &&
attributes["ecstat#{index}"] == 10
1 # No
else
0 # Yes
end
end
def previous_postcode_known(xml_doc, previous_postcode, prevloc)
previous_postcode_known = string_or_nil(xml_doc, "Q12bnot")
if previous_postcode_known == "Temporary_or_Unknown" || (previous_postcode.nil? && prevloc.present?)
1 # not known
elsif previous_postcode.nil?
nil
else
0 # known
end
end
def london_affordable_rent(xml_doc)
lar = unsafe_string_as_integer(xml_doc, "LAR")
if lar == 1
1
else
# We default to No for any other values (nil, not known)
2
end
end
def renewal(rsnvac)
# Relet – renewal of fixed-term tenancy
if rsnvac == 14
1
else
0
end
end
# Letters should be lowercase to match case
def housing_needs(xml_doc, letter)
housing_need = string_or_nil(xml_doc, "Q10-#{letter}")
if housing_need == "Yes"
1
else
0
end
end
def net_income_known(xml_doc, earnings)
incref = string_or_nil(xml_doc, "Q8Refused")
if incref == "Refused"
# Tenant prefers not to say
2
elsif earnings.nil?
# No
1
else
# Yes
0
end
end
def illness_type(xml_doc, index, illness)
illness_type = string_or_nil(xml_doc, "Q10ib-#{index}")
if illness_type == "Yes" && illness == 1
1
elsif illness == 1
0
end
end
def first_time_let(rsnvac)
if [15, 16, 17].include?(rsnvac)
1
else
0
end
end
def declaration(xml_doc)
declaration = string_or_nil(xml_doc, "Qdp")
if declaration == "Yes"
1
end
end
def postcode_known(attributes)
if attributes["postcode_full"].nil? && attributes["la"].nil?
nil
elsif attributes["postcode_full"].nil?
0 # Assumes we selected No in the form since the LA is present
else
1
end
end
def household_members(xml_doc, previous_status)
hhmemb = safe_string_as_integer(xml_doc, "HHMEMB")
if previous_status.include?("submitted") && hhmemb.nil?
hhmemb = people_with_details(xml_doc).count
return nil if hhmemb.zero?
end
hhmemb
end
def people_with_details(xml_doc)
((2..8).map { |x| string_or_nil(xml_doc, "P#{x}Rel") } + [string_or_nil(xml_doc, "P1Sex")]).compact
end
def people_with_details_ids(xml_doc)
[1] + (2..8).select do |x|
string_or_nil(xml_doc, "P#{x}Rel").present? ||
string_or_nil(xml_doc, "P#{x}Sex").present? ||
string_or_nil(xml_doc, "P#{x}Age").present? ||
string_or_nil(xml_doc, "P#{x}Eco").present?
end
end
def tshortfall_known?(xml_doc, attributes)
if attributes["tshortfall"].blank? && attributes["hbrentshortfall"] == 1 && overridden?(xml_doc, "xmlns", "Q18dyes")
1
else
0
end
end
def allocation_system(value)
case value
when 1
1
when 2
0
end
end
def allocation_system_unknown(cbl, chr, cap)
allocation_values = [cbl, chr, cap]
if allocation_values.all?(&:nil?)
nil
elsif allocation_values.all? { |att| att&.zero? }
1
else
0
end
end
def apply_date_consistency!(attributes)
return if attributes["voiddate"].nil? || attributes["startdate"].nil?
if attributes["voiddate"] > attributes["startdate"]
attributes.delete("voiddate")
end
end
def apply_household_consistency!(attributes)
(2..8).each do |index|
next if attributes["age#{index}"].nil?
if attributes["age#{index}"] < 16 && attributes["relat#{index}"] == "R"
attributes["relat#{index}"] = "C"
end
end
end
def household_charge(xml_doc)
value = string_or_nil(xml_doc, "Q18c")
start_year = Integer(get_form_name_component(xml_doc, FORM_NAME_INDEX[:start_year]))
if start_year <= 2021
# Yes means that there are no charges (2021 or earlier)
value && value.include?("Yes") ? 1 : 0
else
# Yes means that there are charges (2022 onwards)
value && value.include?("Yes") ? 0 : 1
end
end
def set_partial_charges_to_zero(attributes)
unless attributes["brent"].nil? &&
attributes["scharge"].nil? &&
attributes["pscharge"].nil? &&
attributes["supcharg"].nil?
attributes["brent"] ||= BigDecimal("0.0")
attributes["scharge"] ||= BigDecimal("0.0")
attributes["pscharge"] ||= BigDecimal("0.0")
attributes["supcharg"] ||= BigDecimal("0.0")
end
end
def is_carehome(scheme)
return nil unless scheme
if [2, 3, 4].include?(scheme.registered_under_care_act_before_type_cast)
1
else
0
end
end
def create_organisation_relationship!(attributes)
parent_organisation_id = attributes["owning_organisation_id"]
child_organisation_id = attributes["managing_organisation_id"]
return if parent_organisation_id == child_organisation_id
OrganisationRelationship.find_or_create_by!(parent_organisation_id:, child_organisation_id:)
end
def address_given?(attributes)
attributes["address_line1"].present? && attributes["town_or_city"].present?
end
end
end

128
app/services/imports/logs_import_service.rb

@ -1,128 +0,0 @@
module Imports
class LogsImportService < ImportService
private
# Safe: A string that represents only an integer (or empty/nil)
def safe_string_as_integer(xml_doc, attribute)
str = field_value(xml_doc, "xmlns", attribute)
Integer(str, exception: false)
end
# Unsafe: A string that has more than just the integer value
def unsafe_string_as_integer(xml_doc, attribute)
str = string_or_nil(xml_doc, attribute)
str&.to_i
end
def compose_date(xml_doc, day_str, month_str, year_str)
day = Integer(field_value(xml_doc, "xmlns", day_str), exception: false)
month = Integer(field_value(xml_doc, "xmlns", month_str), exception: false)
year = Integer(field_value(xml_doc, "xmlns", year_str), exception: false)
if day.nil? || month.nil? || year.nil?
nil
else
Time.zone.local(year, month, day)
end
end
def creation_method(xml_doc)
upload_id = meta_field_value(xml_doc, "upload-id")
upload_id.present? ? "bulk upload" : "single log"
end
def find_organisation_id(xml_doc, id_field)
old_org_id = meta_field_value(xml_doc, id_field)&.strip.presence
organisation = Organisation.find_by(old_org_id:)
raise "Organisation not found with old org ID #{old_org_id}" if organisation.nil?
organisation.id
end
def string_or_nil(xml_doc, attribute)
str = field_value(xml_doc, "xmlns", attribute)
str.presence
end
def ethnic_group(ethnic)
case ethnic
when 1, 2, 3, 18
# White
0
when 4, 5, 6, 7
# Mixed
1
when 8, 9, 10, 11, 15
# Asian
2
when 12, 13, 14
# Black
3
when 16, 19
# Others
4
when 17
# Refused
17
end
end
# Safe: A string that represents only a decimal (or empty/nil)
def safe_string_as_decimal(xml_doc, attribute)
str = string_or_nil(xml_doc, attribute)
if str.nil?
nil
else
BigDecimal(str, exception: false)&.round(2)
end
end
def compose_postcode(xml_doc, outcode, incode)
outcode_value = string_or_nil(xml_doc, outcode)&.strip
incode_value = string_or_nil(xml_doc, incode)&.strip
if outcode_value.nil? || incode_value.nil? || !"#{outcode_value} #{incode_value}".match(POSTCODE_REGEXP)
nil
else
"#{outcode_value} #{incode_value}"
end
end
def previous_postcode_known(xml_doc, previous_postcode, prevloc)
previous_postcode_known = string_or_nil(xml_doc, "Q7UnknownPostcode")
if previous_postcode_known == "If postcode not known tick" || (previous_postcode.nil? && prevloc.present?)
1
elsif previous_postcode.nil?
nil
else
0
end
end
def sex(xml_doc, index)
sex = string_or_nil(xml_doc, "P#{index}Sex")
case sex
when "Male"
"M"
when "Female"
"F"
when "Other", "Non-binary"
"X"
when "Refused", "Person prefers not to say", "Buyer prefers not to say"
"R"
end
end
def relat(xml_doc, index)
relat = string_or_nil(xml_doc, "P#{index}Rel")
case relat
when "Child"
"C"
when "Partner"
"P"
when "Other", "Non-binary"
"X"
when "Refused", "Person prefers not to say", "Buyer prefers not to say"
"R"
end
end
end
end

53
app/services/imports/organisation_import_service.rb

@ -1,53 +0,0 @@
module Imports
class OrganisationImportService < ImportService
def create_organisations(folder)
import_from(folder, :create_organisation)
end
private
PROVIDER_TYPE = {
"HOUSING-ASSOCIATION" => Organisation.provider_types[:PRP],
"LOCAL-AUTHORITY" => Organisation.provider_types[:LA],
}.freeze
def create_organisation(xml_document)
old_visible_id = organisation_field_value(xml_document, "visible-id")
Organisation.create!(
name: organisation_field_value(xml_document, "name"),
provider_type: PROVIDER_TYPE[organisation_field_value(xml_document, "institution-type")],
phone: organisation_field_value(xml_document, "telephone-number"),
holds_own_stock: to_boolean(organisation_field_value(xml_document, "holds-stock")),
active: to_boolean(organisation_field_value(xml_document, "active")),
old_association_type: organisation_field_value(xml_document, "old-association-type"),
software_supplier_id: organisation_field_value(xml_document, "software-supplier-id"),
housing_management_system: organisation_field_value(xml_document, "housing-management-system"),
choice_based_lettings: to_boolean(organisation_field_value(xml_document, "choice-based-lettings")),
common_housing_register: to_boolean(organisation_field_value(xml_document, "common-housing-register")),
choice_allocation_policy: to_boolean(organisation_field_value(xml_document, "choice-allocation-policy")),
cbl_proportion_percentage: organisation_field_value(xml_document, "cbl-proportion-percentage"),
enter_affordable_logs: to_boolean(organisation_field_value(xml_document, "enter-affordable-logs")),
owns_affordable_logs: to_boolean(organisation_field_value(xml_document, "owns-affordable-rent")),
housing_registration_no: organisation_field_value(xml_document, "housing-registration-no"),
general_needs_units: organisation_field_value(xml_document, "general-needs-units"),
supported_housing_units: organisation_field_value(xml_document, "supported-housing-units"),
unspecified_units: organisation_field_value(xml_document, "unspecified-units"),
old_org_id: organisation_field_value(xml_document, "id"),
old_visible_id:,
)
rescue ActiveRecord::RecordNotUnique
name = organisation_field_value(xml_document, "name")
@logger.warn("Organisation #{name} is already present with old visible ID #{old_visible_id}, skipping.")
rescue ActiveRecord::RecordInvalid
@logger.error("Organisation #{old_visible_id}: Failed to import")
raise
end
def organisation_field_value(xml_document, field)
field_value(xml_document, "institution", field)
rescue Nokogiri::SyntaxError
field_value(xml_document, nil, field)
end
end
end

22
app/services/imports/organisation_rent_period_import_service.rb

@ -1,22 +0,0 @@
module Imports
class OrganisationRentPeriodImportService < ImportService
def create_organisation_rent_periods(folder)
import_from(folder, :create_organisation_rent_period)
end
private
def create_organisation_rent_period(xml_document)
organisation = Organisation.find_by(old_org_id: record_field_value(xml_document, "institution"))
OrganisationRentPeriod.create!(
organisation:,
rent_period: Integer(record_field_value(xml_document, "period")),
)
end
def record_field_value(xml_document, field)
field_value(xml_document, "rent-period", field)
end
end
end

95
app/services/imports/sales_logs_field_import_service.rb

@ -1,95 +0,0 @@
module Imports
class SalesLogsFieldImportService < LogsImportService
def update_field(field, folder)
case field
when "creation_method"
import_from(folder, :update_creation_method)
when "owning_organisation_id"
import_from(folder, :update_owning_organisation_id)
when "old_form_id"
import_from(folder, :update_old_form_id)
when "created_by"
import_from(folder, :update_created_by)
else
raise "Updating #{field} is not supported by the field import service"
end
end
private
def update_creation_method(xml_doc)
return unless meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
log = SalesLog.find_by(old_id:)
return @logger.warn "sales log with old id #{old_id} not found" unless log
upload_id = meta_field_value(xml_doc, "upload-id")
if upload_id.nil?
@logger.info "sales log with old id #{old_id} entered manually, no need for update"
elsif log.creation_method_bulk_upload?
@logger.info "sales log #{log.id} creation method already set to bulk upload, no need for update"
else
log.creation_method_bulk_upload!
@logger.info "sales log #{log.id} creation method set to bulk upload"
end
end
def update_owning_organisation_id(xml_doc)
return unless meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = SalesLog.find_by(old_id:)
if record.present?
if record.owning_organisation_id.present?
@logger.info("sales log #{record.id} has a value for owning_organisation_id, skipping update")
else
owning_organisation_id = find_organisation_id(xml_doc, "owner-institution-id")
record.update!(owning_organisation_id:)
@logger.info("sales log #{record.id}'s owning_organisation_id value has been set to #{owning_organisation_id}")
end
else
@logger.warn("sales log with old id #{old_id} not found")
end
end
def update_old_form_id(xml_doc)
return unless meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = SalesLog.find_by(old_id:)
if record.present?
if record.old_form_id.present?
@logger.info("sales log #{record.id} has a value for old_form_id, skipping update")
else
old_form_id = safe_string_as_integer(xml_doc, "Form")
record.update!(old_form_id:)
@logger.info("sales log #{record.id}'s old_form_id value has been set to #{old_form_id}")
end
else
@logger.warn("sales log with old id #{old_id} not found")
end
end
# deletes and recreates the entire record if created_by is missing
def update_created_by(xml_doc)
return unless meta_field_value(xml_doc, "form-name").include?("Sales")
old_id = meta_field_value(xml_doc, "document-id")
record = SalesLog.find_by(old_id:)
return @logger.warn("sales log with old id #{old_id} not found") unless record
return @logger.info("sales log #{record.id} has created_by value, skipping update") if record.created_by.present?
record.destroy!
@logger.info("sales log #{record.id} has been deleted")
log_import_service = Imports::SalesLogsImportService.new(nil, @logger)
log_import_service.send(:create_log, xml_doc)
@logger.info("sales log \"#{record.old_id}\" has been reimported with id #{record.id}")
end
end
end

666
app/services/imports/sales_logs_import_service.rb

@ -1,666 +0,0 @@
module Imports
class SalesLogsImportService < LogsImportService
include CollectionTimeHelper
def initialize(storage_service, logger = Rails.logger, allow_updates: false)
@logs_with_discrepancies = Set.new
@logs_overridden = Set.new
super
end
def create_logs(folder)
import_from(folder, :create_log)
end
private
def create_log(xml_doc)
# only import sales logs from 22/23 collection period onwards
return unless meta_field_value(xml_doc, "form-name").include?("Sales")
return unless (compose_date(xml_doc, "DAY", "MONTH", "YEAR") || Time.zone.parse(field_value(xml_doc, "xmlns", "CompletionDate"))) >= Time.zone.local(2022, 4, 1)
attributes = {}
previous_status = meta_field_value(xml_doc, "status")
# Required fields for status complete or logic to work
# Note: order matters when we derive from previous values (attributes parameter)
attributes["saledate"] = compose_date(xml_doc, "DAY", "MONTH", "YEAR") || Time.zone.parse(field_value(xml_doc, "xmlns", "CompletionDate"))
attributes["owning_organisation_id"] = find_organisation_id(xml_doc, "owner-institution-id")
attributes["type"] = unsafe_string_as_integer(xml_doc, "DerSaleType")
attributes["old_id"] = meta_field_value(xml_doc, "document-id")
attributes["old_form_id"] = safe_string_as_integer(xml_doc, "Form")
attributes["creation_method"] = creation_method(xml_doc)
attributes["created_at"] = Time.zone.parse(meta_field_value(xml_doc, "created-date"))
attributes["updated_at"] = Time.zone.parse(meta_field_value(xml_doc, "modified-date"))
attributes["purchid"] = string_or_nil(xml_doc, "PurchaserCode")
attributes["ownershipsch"] = unsafe_string_as_integer(xml_doc, "Ownership")
attributes["ownershipsch"] = ownership_from_type(attributes) if attributes["ownershipsch"].blank? # sometimes Ownership is missing, but type is set
attributes["othtype"] = string_or_nil(xml_doc, "Q38OtherSale")
attributes["jointpur"] = unsafe_string_as_integer(xml_doc, "joint")
attributes["jointmore"] = unsafe_string_as_integer(xml_doc, "JointMore") || 3 if attributes["jointpur"] == 1
attributes["beds"] = safe_string_as_integer(xml_doc, "Q11Bedrooms")
attributes["companybuy"] = unsafe_string_as_integer(xml_doc, "company") if attributes["ownershipsch"] == 3
attributes["hholdcount"] = other_household_members(xml_doc, attributes)
attributes["hhmemb"] = household_members(xml_doc, attributes)
(1..6).each do |index|
attributes["age#{index}"] = safe_string_as_integer(xml_doc, "P#{index}Age")
attributes["sex#{index}"] = sex(xml_doc, index)
attributes["ecstat#{index}"] = unsafe_string_as_integer(xml_doc, "P#{index}Eco")
attributes["age#{index}_known"] = age_known(xml_doc, index, attributes["hhmemb"], attributes["age#{index}"])
end
(2..6).each do |index|
attributes["relat#{index}"] = relat(xml_doc, index)
attributes["details_known_#{index}"] = details_known(index, attributes)
end
attributes["national"] = unsafe_string_as_integer(xml_doc, "P1Nat")
attributes["ethnic"] = unsafe_string_as_integer(xml_doc, "P1Eth")
attributes["ethnic_group"] = ethnic_group(attributes["ethnic"])
attributes["buy1livein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer1")
attributes["buylivein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer") if attributes["ownershipsch"] == 3
attributes["builtype"] = unsafe_string_as_integer(xml_doc, "Q13BuildingType")
attributes["proptype"] = unsafe_string_as_integer(xml_doc, "Q12PropertyType")
attributes["privacynotice"] = 1 if string_or_nil(xml_doc, "Qdp") == "Yes"
attributes["noint"] = unsafe_string_as_integer(xml_doc, "PartAPurchaser")
attributes["buy2livein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer2")
attributes["wheel"] = unsafe_string_as_integer(xml_doc, "Q10Wheelchair")
attributes["la"] = string_or_nil(xml_doc, "Q14ONSLACode")
attributes["income1"] = safe_string_as_integer(xml_doc, "Q2Person1Income")
attributes["income1nk"] = income_known(unsafe_string_as_integer(xml_doc, "P1IncKnown"))
attributes["income1nk"] ||= 0 if attributes["income1"].present?
attributes["inc1mort"] = unsafe_string_as_integer(xml_doc, "Q2Person1Mortgage")
attributes["income2"] = safe_string_as_integer(xml_doc, "Q2Person2Income")
attributes["income2nk"] = income_known(unsafe_string_as_integer(xml_doc, "P2IncKnown"))
attributes["income2nk"] ||= 0 if attributes["income2"].present?
attributes["savings"] = safe_string_as_integer(xml_doc, "Q3Savings")&.round(-1)
attributes["savingsnk"] = savings_known(xml_doc)
attributes["savingsnk"] ||= 0 if attributes["savings"].present?
attributes["prevown"] = unsafe_string_as_integer(xml_doc, "Q4PrevOwnedProperty")
attributes["mortgage"] = safe_string_as_decimal(xml_doc, "CALCMORT")
attributes["inc2mort"] = unsafe_string_as_integer(xml_doc, "Q2Person2MortApplication")
attributes["hb"] = unsafe_string_as_integer(xml_doc, "Q2a")
attributes["frombeds"] = safe_string_as_integer(xml_doc, "Q20Bedrooms")
attributes["staircase"] = unsafe_string_as_integer(xml_doc, "Q17aStaircase") if attributes["ownershipsch"] == 1
attributes["stairbought"] = safe_string_as_integer(xml_doc, "PercentBought")
attributes["stairowned"] = safe_string_as_integer(xml_doc, "PercentOwns") if attributes["staircase"] == 1
attributes["mrent"] = safe_string_as_decimal(xml_doc, "Q28MonthlyRent")
attributes["exdate"] = compose_date(xml_doc, "EXDAY", "EXMONTH", "EXYEAR")
attributes["exday"] = safe_string_as_integer(xml_doc, "EXDAY")
attributes["exmonth"] = safe_string_as_integer(xml_doc, "EXMONTH")
attributes["exyear"] = safe_string_as_integer(xml_doc, "EXYEAR")
attributes["resale"] = unsafe_string_as_integer(xml_doc, "Q17Resale")
attributes["deposit"] = deposit(xml_doc, attributes)
attributes["cashdis"] = safe_string_as_decimal(xml_doc, "Q27SocialHomeBuy")
attributes["disabled"] = unsafe_string_as_integer(xml_doc, "Disability")
attributes["lanomagr"] = unsafe_string_as_integer(xml_doc, "Q19Rehoused")
attributes["value"] = purchase_price(xml_doc, attributes)
attributes["equity"] = safe_string_as_decimal(xml_doc, "Q23Equity")
attributes["discount"] = safe_string_as_decimal(xml_doc, "Q33Discount")
attributes["grant"] = safe_string_as_decimal(xml_doc, "Q32Reductions")
attributes["pregyrha"] = 1 if string_or_nil(xml_doc, "PREGYRHA") == "Yes"
attributes["pregla"] = 1 if string_or_nil(xml_doc, "PREGLA") == "Yes"
attributes["pregghb"] = 1 if string_or_nil(xml_doc, "PREGHBA") == "Yes"
attributes["pregother"] = 1 if string_or_nil(xml_doc, "PREGOTHER") == "Yes"
attributes["ppostcode_full"] = parse_postcode(string_or_nil(xml_doc, "Q7Postcode"))
attributes["prevloc"] = string_or_nil(xml_doc, "Q7ONSLACode")
attributes["ppcodenk"] = previous_postcode_known(xml_doc, attributes["ppostcode_full"], attributes["prevloc"]) # Q7UNKNOWNPOSTCODE check mapping
attributes["ppostc1"] = string_or_nil(xml_doc, "PPOSTC1")
attributes["ppostc2"] = string_or_nil(xml_doc, "PPOSTC2")
attributes["hhregres"] = unsafe_string_as_integer(xml_doc, "ArmedF")
attributes["hhregresstill"] = still_serving(xml_doc)
attributes["proplen"] = safe_string_as_integer(xml_doc, "Q16aProplen2") || safe_string_as_integer(xml_doc, "Q16aProplensec2")
attributes["mscharge"] = monthly_charges(xml_doc, attributes)
attributes["has_mscharge"] = 1 if attributes["mscharge"]&.positive?
attributes["has_mscharge"] = 0 if attributes["mscharge"].present? && attributes["mscharge"] <= 0
attributes["prevten"] = unsafe_string_as_integer(xml_doc, "Q6PrevTenure")
attributes["mortlen"] = mortgage_length(xml_doc, attributes)
attributes["extrabor"] = borrowing(xml_doc, attributes)
attributes["mortgageused"] = mortgage_used(xml_doc, attributes)
attributes["wchair"] = unsafe_string_as_integer(xml_doc, "Q15Wheelchair")
attributes["armedforcesspouse"] = unsafe_string_as_integer(xml_doc, "ARMEDFORCESSPOUSE")
attributes["hodate"] = compose_date(xml_doc, "HODAY", "HOMONTH", "HOYEAR")
attributes["hoday"] = safe_string_as_integer(xml_doc, "HODAY")
attributes["homonth"] = safe_string_as_integer(xml_doc, "HOMONTH")
attributes["hoyear"] = safe_string_as_integer(xml_doc, "HOYEAR")
attributes["fromprop"] = unsafe_string_as_integer(xml_doc, "Q21PropertyType")
attributes["socprevten"] = unsafe_string_as_integer(xml_doc, "PrevRentType")
attributes["mortgagelender"] = mortgage_lender(xml_doc, attributes)
attributes["mortgagelenderother"] = mortgage_lender_other(xml_doc, attributes)
attributes["postcode_full"] = parse_postcode(string_or_nil(xml_doc, "Q14Postcode"))
attributes["pcodenk"] = 0 if attributes["postcode_full"].present? # known if given
attributes["soctenant"] = 0 if set_soctenant_fields?(attributes)
attributes["previous_la_known"] = 1 if attributes["prevloc"].present?
if attributes["la"].present?
attributes["la_known"] = 1
attributes["is_la_inferred"] = false
end
# Soft validations can become required answers, set them to yes by default
attributes["mortgage_value_check"] = 0
attributes["shared_ownership_deposit_value_check"] = 0
attributes["value_value_check"] = 0
attributes["savings_value_check"] = 0
attributes["income1_value_check"] = 0
attributes["deposit_value_check"] = 0
attributes["wheel_value_check"] = 0
attributes["retirement_value_check"] = 0
attributes["extrabor_value_check"] = 0
attributes["grant_value_check"] = 0
attributes["staircase_bought_value_check"] = 0
attributes["deposit_and_mortgage_value_check"] = 0
attributes["old_persons_shared_ownership_value_check"] = 0
attributes["income2_value_check"] = 0
attributes["monthly_charges_value_check"] = 0
attributes["student_not_child_value_check"] = 0
attributes["discounted_sale_value_check"] = 0
attributes["buyer_livein_value_check"] = 0
attributes["percentage_discount_value_check"] = 0
attributes["hodate_check"] = 0
attributes["saledate_check"] = 0
attributes["combined_income_value_check"] = 0
attributes["stairowned_value_check"] = 0
# 2023/34 attributes
attributes["address_line1"] = string_or_nil(xml_doc, "AddressLine1")
attributes["address_line2"] = string_or_nil(xml_doc, "AddressLine2")
attributes["town_or_city"] = string_or_nil(xml_doc, "TownCity")
attributes["county"] = string_or_nil(xml_doc, "County")
attributes["uprn"] = address_given?(attributes) ? nil : string_or_nil(xml_doc, "UPRN")
attributes["uprn_known"] = attributes["uprn"].present? ? 1 : 0
attributes["uprn_confirmed"] = attributes["uprn"].present? ? 1 : 0
attributes["proplen_asked"] = 0 if attributes["proplen"]&.positive?
attributes["proplen_asked"] = 1 if attributes["proplen"]&.zero?
attributes["prevshared"] = unsafe_string_as_integer(xml_doc, "PREVSHARED")
attributes["ethnicbuy2"] = unsafe_string_as_integer(xml_doc, "P2Eth")
attributes["ethnic_group2"] = ethnic_group(attributes["ethnicbuy2"])
attributes["nationalbuy2"] = unsafe_string_as_integer(xml_doc, "P2Nat")
attributes["buy2living"] = unsafe_string_as_integer(xml_doc, "BUY2LIVEIN")
attributes["staircasesale"] = unsafe_string_as_integer(xml_doc, "STAIRCASESALE")
attributes["prevtenbuy2"] = unsafe_string_as_integer(xml_doc, "PREVTENBUY2")
# Sets the log creator
owner_id = meta_field_value(xml_doc, "owner-user-id").strip
user = LegacyUser.find_by(old_user_id: owner_id)&.user
if owner_id.blank? || user.blank? || user.organisation_id != attributes["owning_organisation_id"]
if owner_id.blank?
@logger.error("Sales log '#{attributes['old_id']}' does not have the owner id. Assigning log to 'Unassigned' user.")
elsif user.blank?
@logger.error("Sales log '#{attributes['old_id']}' belongs to legacy user with owner-user-id: '#{owner_id}' which cannot be found. Assigning log to 'Unassigned' user.")
else
@logger.error("Sales log '#{attributes['old_id']}' belongs to legacy user with owner-user-id: '#{owner_id}' which belongs to a different organisation. Assigning log to 'Unassigned' user.")
end
if User.find_by(name: "Unassigned", organisation_id: attributes["owning_organisation_id"])
user = User.find_by(name: "Unassigned", organisation_id: attributes["owning_organisation_id"])
else
user = User.new(
name: "Unassigned",
organisation_id: attributes["owning_organisation_id"],
is_dpo: false,
encrypted_password: SecureRandom.hex(10),
email: SecureRandom.uuid,
confirmed_at: Time.zone.now,
active: false,
)
user.save!(validate: false)
end
attributes["created_by"] = user
end
attributes["values_updated_at"] = Time.zone.now
set_default_values(attributes) if previous_status.include?("submitted")
sales_log = save_sales_log(attributes, previous_status)
compute_differences(sales_log, attributes)
check_status_completed(sales_log, previous_status) unless @logs_overridden.include?(sales_log.old_id)
end
def save_sales_log(attributes, previous_status)
sales_log = SalesLog.new(attributes)
begin
legacy_id = attributes["old_id"]
record = SalesLog.find_by(old_id: legacy_id)
if record.present?
if allow_updates
attributes["updated_at"] = Time.zone.now
record.update!(attributes)
end
record
else
duplicate_logs = sales_log.owning_organisation.owned_sales_logs.not_imported.duplicate_logs(sales_log)
if duplicate_logs.count.positive?
@logger.info("Duplicate log with id #{duplicate_logs.map(&:id).join(', ')} found for log #{sales_log.old_id}, skipping log")
else
sales_log.save!
end
sales_log
end
rescue ActiveRecord::RecordInvalid => e
rescue_validation_or_raise(sales_log, attributes, previous_status, e)
end
end
def rescue_validation_or_raise(sales_log, attributes, previous_status, exception)
if %w[saved submitted-invalid].include?(previous_status)
sales_log.errors.each do |error|
unless error.attribute == :type || error.attribute == :ownershipsch
attributes.delete(error.attribute.to_s)
end
attributes.delete("pcodenk") if error.attribute == :postcode_full
attributes.delete("ppcodenk") if error.attribute == :ppostcode_full
end
@logs_overridden << sales_log.old_id
return save_sales_log(attributes, previous_status)
end
errors = {
%i[postcode_full postcodes_not_matching] => %w[ppcodenk ppostcode_full],
%i[exdate over_a_year_from_saledate] => %w[exdate],
%i[income1 over_hard_max_for_outside_london] => %w[income1],
%i[income1 over_combined_hard_max_for_outside_london] => %w[income1 income2],
%i[income1 over_hard_max_for_london] => %w[income1],
%i[income1 over_combined_hard_max_for_london] => %w[income1 income2],
%i[income2 over_hard_max_for_outside_london] => %w[income2],
%i[income2 over_combined_hard_max_for_outside_london] => %w[income1 income2],
%i[income2 over_hard_max_for_london] => %w[income2],
%i[income2 over_combined_hard_max_for_london] => %w[income1 income2],
%i[equity over_max] => %w[equity],
%i[equity under_min] => %w[equity],
%i[mscharge under_min] => %w[mscharge has_mscharge],
%i[mortgage cannot_be_0] => %w[mortgage],
%i[frombeds outside_the_range] => %w[frombeds],
%i[age1 outside_the_range] => %w[age1 age1_known],
%i[proplen outside_the_range] => %w[proplen],
}
errors.each do |(error, fields)|
next unless sales_log.errors.of_kind?(*error)
fields.each do |field|
attributes.delete(field)
end
@logs_overridden << sales_log.old_id
return save_sales_log(attributes, previous_status)
end
if sales_log.errors.of_kind?(:postcode_full, :wrong_format)
@logs_overridden << sales_log.old_id
attributes.delete("postcode_full")
attributes["pcodenk"] = attributes["la"].present? ? 1 : nil
save_sales_log(attributes, previous_status)
elsif sales_log.errors.of_kind?(:ppostcode_full, :wrong_format)
@logs_overridden << sales_log.old_id
attributes.delete("ppostcode_full")
attributes["ppcodenk"] = attributes["prevloc"].present? ? 1 : nil
save_sales_log(attributes, previous_status)
elsif sales_log.errors.of_kind?(:uprn, :uprn_error)
@logs_overridden << sales_log.old_id
attributes["uprn_known"] = 0
save_sales_log(attributes, previous_status)
else
@logger.error("Log #{sales_log.old_id}: Failed to import")
sales_log.errors.each do |error|
@logger.error("Validation error: Field #{error.attribute}:")
@logger.error("\tOwning Organisation: #{sales_log.owning_organisation&.name}")
@logger.error("\tOld CORE ID: #{sales_log.old_id}")
@logger.error("\tOld CORE: #{attributes[error.attribute.to_s]&.inspect}")
@logger.error("\tNew CORE: #{sales_log.read_attribute(error.attribute)&.inspect}")
@logger.error("\tError message: #{error.type}")
end
raise exception
end
end
def compute_differences(sales_log, attributes)
differences = []
attributes.each do |key, value|
sales_log_value = sales_log.send(key.to_sym)
next if fields_not_present_in_softwire_data.include?(key)
if value != sales_log_value
differences.push("#{key} #{value.inspect} #{sales_log_value.inspect}")
end
end
end
def fields_not_present_in_softwire_data
%w[created_by
income1_value_check
income2_value_check
mortgage_value_check
savings_value_check
deposit_value_check
wheel_value_check
retirement_value_check
extrabor_value_check
deposit_and_mortgage_value_check
shared_ownership_deposit_value_check
grant_value_check
value_value_check
old_persons_shared_ownership_value_check
staircase_bought_value_check
monthly_charges_value_check
hodate_check
saledate_check
student_not_child_value_check
discounted_sale_value_check
buyer_livein_value_check
percentage_discount_value_check
combined_income_value_check
stairowned_value_check
uprn_known
uprn_confirmed]
end
def check_status_completed(sales_log, previous_status)
if previous_status.include?("submitted") && sales_log.status != "completed"
@logs_with_discrepancies << sales_log.old_id
end
end
def age_known(_xml_doc, index, hhmemb, age)
return nil if hhmemb.present? && index > hhmemb
return 0 if age.present?
end
def details_known(index, attributes)
return nil if attributes["hhmemb"].nil? || index > attributes["hhmemb"]
return nil if attributes["jointpur"] == 1 && index == 2
if attributes["age#{index}_known"] != 0 &&
attributes["sex#{index}"] == "R" &&
attributes["relat#{index}"] == "R" &&
attributes["ecstat#{index}"] == 10
2 # No
else
1 # Yes
end
end
MORTGAGE_LENDER_OPTIONS = {
"atom bank" => 1,
"barclays bank plc" => 2,
"bath building society" => 3,
"buckinghamshire building society" => 4,
"cambridge building society" => 5,
"coventry building society" => 6,
"cumberland building society" => 7,
"darlington building society" => 8,
"dudley building society" => 9,
"ecology building society" => 10,
"halifax" => 11,
"hanley economic building society" => 12,
"hinckley and rugby building society" => 13,
"holmesdale building society" => 14,
"ipswich building society" => 15,
"leeds building society" => 16,
"lloyds bank" => 17,
"mansfield building society" => 18,
"market harborough building society" => 19,
"melton mowbray building society" => 20,
"nationwide building society" => 21,
"natwest" => 22,
"nedbank private wealth" => 23,
"newbury building society" => 24,
"oneSavings bank" => 25,
"parity trust" => 26,
"penrith building society" => 27,
"pepper homeloans" => 28,
"royal bank of scotland" => 29,
"santander" => 30,
"skipton building society" => 31,
"teachers building society" => 32,
"the co-operative bank" => 33,
"tipton & coseley building society" => 34,
"tss" => 35,
"ulster bank" => 36,
"virgin money" => 37,
"west bromwich building society" => 38,
"yorkshire building society" => 39,
"other" => 40,
}.freeze
# this comes through as a string, need to map to a corresponding integer
def mortgage_lender(xml_doc, attributes)
lender = case attributes["ownershipsch"]
when 1
string_or_nil(xml_doc, "Q24aMortgageLender")
when 2
string_or_nil(xml_doc, "Q34a")
when 3
string_or_nil(xml_doc, "Q41aMortgageLender")
end
return if lender.blank?
MORTGAGE_LENDER_OPTIONS[lender.downcase] || MORTGAGE_LENDER_OPTIONS["other"]
end
def mortgage_lender_other(xml_doc, attributes)
return unless attributes["mortgagelender"] == MORTGAGE_LENDER_OPTIONS["other"]
case attributes["ownershipsch"]
when 1
string_or_nil(xml_doc, "Q24aMortgageLender")
when 2
string_or_nil(xml_doc, "Q34a")
when 3
string_or_nil(xml_doc, "Q41aMortgageLender")
end
end
def mortgage_length(xml_doc, attributes)
case attributes["ownershipsch"]
when 1
unsafe_string_as_integer(xml_doc, "Q24b")
when 2
unsafe_string_as_integer(xml_doc, "Q34b")
when 3
unsafe_string_as_integer(xml_doc, "Q41b")
end
end
def savings_known(xml_doc)
case unsafe_string_as_integer(xml_doc, "savingsKnown")
when 1 # known
0
when 2 # unknown
1
end
end
def still_serving(xml_doc)
case unsafe_string_as_integer(xml_doc, "LeftArmedF")
when 4
4
when 5, 6
5
end
end
def income_known(value)
case value
when 1 # known
0
when 2 # unknown
1
end
end
def borrowing(xml_doc, attributes)
case attributes["ownershipsch"]
when 1
unsafe_string_as_integer(xml_doc, "Q25Borrowing")
when 2
unsafe_string_as_integer(xml_doc, "Q35Borrowing")
when 3
unsafe_string_as_integer(xml_doc, "Q42Borrowing")
end
end
def purchase_price(xml_doc, attributes)
case attributes["ownershipsch"]
when 1
safe_string_as_decimal(xml_doc, "Q22PurchasePrice")
when 2
safe_string_as_decimal(xml_doc, "Q31PurchasePrice")
when 3
safe_string_as_decimal(xml_doc, "Q40PurchasePrice")
end
end
def deposit(xml_doc, attributes)
case attributes["ownershipsch"]
when 1
safe_string_as_decimal(xml_doc, "Q26CashDeposit")
when 2
safe_string_as_decimal(xml_doc, "Q36CashDeposit")
when 3
safe_string_as_decimal(xml_doc, "Q43CashDeposit")
end
end
def monthly_charges(xml_doc, attributes)
case attributes["ownershipsch"]
when 1
safe_string_as_decimal(xml_doc, "Q29MonthlyCharges")
when 2
safe_string_as_decimal(xml_doc, "Q37MonthlyCharges")
when 3
safe_string_as_decimal(xml_doc, "Q44MonthlyCharges")
end
end
def ownership_from_type(attributes)
case attributes["type"]
when 2, 24, 18, 16, 28, 31, 30, 32
1 # shared ownership
when 8, 14, 27, 9, 29, 21, 22
2 # discounted ownership
when 10, 12
3 # outright sale
end
end
def other_household_members(xml_doc, attributes)
hholdcount = safe_string_as_integer(xml_doc, "LiveInOther")
return hholdcount if hholdcount.present?
other_people_with_details(xml_doc, attributes)
end
def other_people_with_details(xml_doc, attributes)
number_of_buyers = attributes["jointpur"] == 1 ? 2 : 1
highest_person_index_with_details = number_of_buyers
(2..6).each do |person_index|
age = string_or_nil(xml_doc, "P#{person_index}Age")
gender = string_or_nil(xml_doc, "P#{person_index}Sex")
relationship = string_or_nil(xml_doc, "P#{person_index}Rel")
economic_status = string_or_nil(xml_doc, "P#{person_index}Eco")
if gender.present? || age.present? || relationship.present? || economic_status.present?
highest_person_index_with_details = person_index
end
end
highest_person_index_with_details - number_of_buyers
end
def household_members(_xml_doc, attributes)
if attributes["jointpur"] == 2
attributes["hholdcount"] + 1
else
attributes["hholdcount"] + 2
end
end
def parse_postcode(postcode)
return if postcode.blank?
UKPostcode.parse(postcode).to_s
end
def mortgage_used(xml_doc, attributes)
mortgageused = unsafe_string_as_integer(xml_doc, "MORTGAGEUSED")
return mortgageused unless mortgageused == 3
if attributes["mortgage"].present? || attributes["mortlen"].present? || attributes["extrabor"].present?
1 # yes
else
3 # don't know
end
end
def set_soctenant_fields?(attributes)
return false if attributes["ownershipsch"] != 1
%w[socprevten frombeds fromprop].any? { |field| attributes[field].present? } || collection_start_year_for_date(attributes["saledate"]) < 2023
end
def set_default_values(attributes)
attributes["armedforcesspouse"] ||= 7
attributes["hhregres"] ||= 8
attributes["hhregresstill"] ||= 7 if attributes["hhregres"] == 1
attributes["disabled"] ||= 3
attributes["wheel"] ||= 3
attributes["hb"] ||= 4
attributes["prevown"] ||= 3
attributes["savingsnk"] ||= attributes["savings"].present? ? 0 : 1
attributes["inc1mort"] ||= 3
if [attributes["pregyrha"], attributes["pregla"], attributes["pregghb"], attributes["pregother"]].all?(&:blank?)
attributes["pregblank"] = 1
end
attributes["pcodenk"] ||= 1
attributes["prevten"] ||= 0
attributes["extrabor"] ||= 3 if attributes["mortgageused"] == 1
attributes["socprevten"] ||= 10 if set_soctenant_fields?(attributes)
attributes["fromprop"] ||= 0 if set_soctenant_fields?(attributes)
attributes["mortgagelender"] ||= 0 if attributes["mortgageused"] == 1
# buyer 1 characteristics
attributes["age1_known"] ||= 1
attributes["sex1"] ||= "R"
attributes["ethnic_group"] ||= 17
attributes["ethnic"] ||= 17
attributes["national"] ||= 13
attributes["ecstat1"] ||= 10
attributes["income1nk"] ||= attributes["income1"].present? ? 0 : 1
# buyer 2 characteristics
if attributes["jointpur"] == 1
attributes["age2_known"] ||= 1
attributes["sex2"] ||= "R"
attributes["ecstat2"] ||= 10
attributes["income2nk"] ||= attributes["income2"].present? ? 0 : 1
attributes["relat2"] ||= "R"
attributes["inc2mort"] ||= 3
attributes["buy2livein"] ||= 1 unless attributes["ownershipsch"] == 3
attributes["ethnic_group2"] ||= 17
attributes["ethnicbuy2"] ||= 17
attributes["nationalbuy2"] ||= 13
end
# other household members characteristics
(2..[attributes["hhmemb"], 6].min).each do |index|
attributes["age#{index}_known"] ||= 1
attributes["sex#{index}"] ||= "R"
attributes["ecstat#{index}"] ||= 10
attributes["relat#{index}"] ||= "R"
end
end
def missing_answers(sales_log)
applicable_questions = sales_log.form.subsections.map { |s| s.applicable_questions(sales_log).select { |q| q.enabled?(sales_log) } }.flatten
applicable_questions.filter { |q| q.unanswered?(sales_log) }.map(&:id) - sales_log.optional_fields
end
def address_given?(attributes)
attributes["address_line1"].present? && attributes["town_or_city"].present?
end
end
end

62
app/services/imports/scheme_import_service.rb

@ -1,62 +0,0 @@
module Imports
class SchemeImportService < ImportService
def create_schemes(folder)
import_from(folder, :create_scheme)
end
def create_scheme(xml_document)
attributes = scheme_attributes(xml_document)
if attributes["status"] == "Approved"
Scheme.create!(
owning_organisation_id: attributes["owning_organisation_id"],
service_name: attributes["service_name"],
arrangement_type: attributes["arrangement_type"],
old_id: attributes["old_id"],
old_visible_id: attributes["old_visible_id"],
)
else
@logger.warn("Scheme with legacy ID #{attributes['old_id']} is not approved (#{attributes['status']}), skipping")
end
rescue ActiveRecord::RecordInvalid
@logger.error("Scheme #{attributes['old_visible_id']}: Failed to import")
raise
end
private
def scheme_field_value(xml_document, field)
field_value(xml_document, "mgmtgroup", field)
end
def string_or_nil(xml_doc, attribute)
str = scheme_field_value(xml_doc, attribute)
str.presence
end
# Safe: A string that represents only an integer (or empty/nil)
def safe_string_as_integer(xml_doc, attribute)
str = scheme_field_value(xml_doc, attribute)
Integer(str, exception: false)
end
def scheme_attributes(xml_doc)
attributes = {}
attributes["old_id"] = string_or_nil(xml_doc, "id")
attributes["old_visible_id"] = string_or_nil(xml_doc, "visible-id")
attributes["status"] = string_or_nil(xml_doc, "status")
attributes["service_name"] = string_or_nil(xml_doc, "name")
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
end
def find_owning_organisation_id(old_org_id)
organisation = Organisation.find_by(old_org_id:)
raise "Organisation not found with old org ID #{old_org_id}" if organisation.nil?
organisation.id
end
end
end

222
app/services/imports/scheme_location_import_service.rb

@ -1,222 +0,0 @@
module Imports
class SchemeLocationImportService < ImportService
def create_scheme_locations(folder)
import_from(folder, :create_scheme_location)
end
def create_scheme_location(xml_document)
attributes = scheme_attributes(xml_document)
schemes = Scheme.where(old_id: attributes["scheme_old_id"])
raise "Scheme not found with legacy ID #{attributes['scheme_old_id']}" if schemes.empty?
if schemes.size == 1 && schemes.first.locations&.empty?
scheme = update_scheme(schemes.first, attributes)
else
scheme = find_scheme_to_merge(attributes)
scheme ||= duplicate_scheme(schemes, attributes)
end
add_location(scheme, attributes)
end
private
REGISTERED_UNDER_CARE_ACT = {
2 => "(Part-registered care home)",
3 => "(Registered personal care home)",
4 => "(Registered nursing care home)",
}.freeze
def create_scheme(source_scheme, attributes)
scheme = Scheme.new(
scheme_type: attributes["scheme_type"],
registered_under_care_act: attributes["registered_under_care_act"],
support_type: attributes["support_type"],
intended_stay: attributes["intended_stay"],
primary_client_group: attributes["primary_client_group"],
secondary_client_group: attributes["secondary_client_group"],
has_other_client_group: attributes["has_other_client_group"],
sensitive: attributes["sensitive"],
# These values were set by the scheme import (management groups)
owning_organisation_id: source_scheme.owning_organisation_id,
service_name: source_scheme.service_name,
arrangement_type: source_scheme.arrangement_type,
old_id: source_scheme.old_id,
old_visible_id: source_scheme.old_visible_id,
)
confirm_scheme_or_location(scheme)
scheme.save! && scheme
rescue ActiveRecord::RecordInvalid
@logger.error("Scheme #{source_scheme.old_visible_id}: Failed to import")
raise
end
def update_scheme(scheme, attributes)
scheme.attributes = {
scheme_type: attributes["scheme_type"],
registered_under_care_act: attributes["registered_under_care_act"],
support_type: attributes["support_type"],
intended_stay: attributes["intended_stay"],
primary_client_group: attributes["primary_client_group"],
has_other_client_group: attributes["has_other_client_group"],
secondary_client_group: attributes["secondary_client_group"],
sensitive: attributes["sensitive"],
}
confirm_scheme_or_location(scheme)
scheme.save! && scheme
end
def confirm_scheme_or_location(obj)
obj.confirmed = true
obj.validate_confirmed
unless obj.errors.empty?
obj.confirmed = false
obj.errors.clear
end
end
def scheme_attributes(xml_doc)
attributes = {}
attributes["scheme_type"] = safe_string_as_integer(xml_doc, "scheme-type")
registered_under_care_act = safe_string_as_integer(xml_doc, "reg-home-type")
attributes["registered_under_care_act"] = registered_under_care_act&.zero? ? nil : registered_under_care_act
attributes["support_type"] = support_type(xml_doc)
attributes["intended_stay"] = string_or_nil(xml_doc, "intended-stay")
attributes["mobility_type"] = string_or_nil(xml_doc, "mobility-type")
attributes["primary_client_group"] = string_or_nil(xml_doc, "client-group-1")
attributes["secondary_client_group"] = string_or_nil(xml_doc, "client-group-2")
attributes["secondary_client_group"] = nil if attributes["primary_client_group"] == attributes["secondary_client_group"]
attributes["has_other_client_group"] = attributes["secondary_client_group"].present? ? 1 : 0
attributes["sensitive"] = sensitive(xml_doc)
attributes["start_date"] = parse_date(xml_doc, "start-date")
attributes["end_date"] = parse_date(xml_doc, "end-date")
attributes["location_name"] = string_or_nil(xml_doc, "name")
attributes["postcode"] = string_or_nil(xml_doc, "postcode")
attributes["units"] = safe_string_as_integer(xml_doc, "total-units")
attributes["type_of_unit"] = safe_string_as_integer(xml_doc, "unit-type")
attributes["location_old_id"] = string_or_nil(xml_doc, "id")
attributes["location_old_visible_id"] = string_or_nil(xml_doc, "visible-id")
attributes["scheme_old_id"] = string_or_nil(xml_doc, "mgmtgroup")
attributes["location_code"] = LocationConstants::LA_NAME_TO_CODE[string_or_nil(xml_doc, "local-authority-name")]
attributes
end
def add_location(scheme, attributes)
location = Location.create!(
name: attributes["location_name"],
postcode: attributes["postcode"],
mobility_type: attributes["mobility_type"],
units: attributes["units"],
type_of_unit: attributes["type_of_unit"],
old_visible_id: attributes["location_old_visible_id"],
old_id: attributes["location_old_id"],
startdate: attributes["start_date"],
location_code: attributes["location_code"],
scheme:,
)
if attributes["end_date"]
location.location_deactivation_periods.create!(deactivation_date: attributes["end_date"])
end
confirm_scheme_or_location(location)
location.save! && location
rescue ActiveRecord::RecordNotUnique
@logger.warn("Location is already present with legacy ID #{attributes['location_old_id']}, skipping")
rescue ActiveRecord::RecordInvalid
@logger.error("Location #{attributes['location_old_id']}: Failed to import")
raise
end
def find_scheme_to_merge(attributes)
Scheme.find_by(
old_id: attributes["scheme_old_id"],
scheme_type: attributes["scheme_type"],
registered_under_care_act: attributes["registered_under_care_act"],
support_type: attributes["support_type"],
intended_stay: attributes["intended_stay"],
primary_client_group: attributes["primary_client_group"],
secondary_client_group: attributes["secondary_client_group"],
)
end
def duplicate_scheme(schemes, attributes)
# Since all schemes in the array are different, pick the first one
# In the future, consider a better selection method if needed
old_scheme = schemes.first
new_scheme = create_scheme(old_scheme, attributes)
if old_scheme.scheme_type != new_scheme.scheme_type
rename_schemes(old_scheme, new_scheme, :scheme_type)
elsif old_scheme.registered_under_care_act != new_scheme.registered_under_care_act
rename_registered_care(old_scheme, new_scheme)
elsif old_scheme.support_type != new_scheme.support_type
rename_schemes(old_scheme, new_scheme, :support_type)
elsif old_scheme.intended_stay != new_scheme.intended_stay
rename_schemes(old_scheme, new_scheme, :intended_stay)
elsif old_scheme.primary_client_group != new_scheme.primary_client_group
rename_schemes(old_scheme, new_scheme, :primary_client_group)
elsif old_scheme.secondary_client_group != new_scheme.secondary_client_group
rename_schemes(old_scheme, new_scheme, :secondary_client_group)
end
new_scheme
end
def rename_registered_care(*schemes)
schemes.each do |scheme|
if REGISTERED_UNDER_CARE_ACT.key?(scheme.registered_under_care_act_before_type_cast)
suffix = REGISTERED_UNDER_CARE_ACT[scheme.registered_under_care_act_before_type_cast]
scheme.update!(service_name: "#{scheme.service_name} - #{suffix}")
end
end
end
def rename_schemes(old_scheme, new_scheme, attribute)
old_scheme_attribute = old_scheme.send(attribute)
new_scheme_attribute = new_scheme.send(attribute)
if old_scheme_attribute
old_scheme_name = "#{old_scheme.service_name} - #{old_scheme_attribute}"
old_scheme.update!(service_name: old_scheme_name)
end
if new_scheme_attribute
new_scheme_name = "#{new_scheme.service_name} - #{new_scheme_attribute}"
new_scheme.update!(service_name: new_scheme_name)
end
end
def location_field_value(xml_doc, field)
field_value(xml_doc, "scheme", field)
end
def string_or_nil(xml_doc, attribute)
str = location_field_value(xml_doc, attribute)
str.presence
end
# Safe: A string that represents only an integer (or empty/nil)
def safe_string_as_integer(xml_doc, attribute)
str = location_field_value(xml_doc, attribute)
Integer(str, exception: false)
end
def sensitive(xml_doc)
value = string_or_nil(xml_doc, "sensitive")
if value == "true"
1
else
0
end
end
def parse_date(xml_doc, attribute)
date = string_or_nil(xml_doc, attribute)
Time.zone.parse(date) if date
end
def support_type(xml_doc)
type = safe_string_as_integer(xml_doc, "support-type")
return unless type
Scheme::SUPPORT_TYPE.value?(type) ? type : 0
end
end
end

100
app/services/imports/user_import_service.rb

@ -1,100 +0,0 @@
module Imports
class UserImportService < ImportService
def create_users(folder)
import_from(folder, :create_user)
end
def create_users_who_signed_dpcs(folder)
import_from(folder, :create_user_who_signed_dpc)
end
private
PROVIDER_TYPE = {
"Data Provider" => User.roles[:data_provider],
}.freeze
def create_user(xml_document)
organisation = Organisation.find_by(old_org_id: user_field_value(xml_document, "institution"))
old_user_id = user_field_value(xml_document, "id")
email = user_field_value(xml_document, "email").downcase.strip
name = user_field_value(xml_document, "full-name") || email
deleted = user_field_value(xml_document, "deleted")
if LegacyUser.find_by(old_user_id:)
@logger.warn("User #{name} with old user id #{old_user_id} is already present, skipping.")
elsif deleted == "true"
@logger.warn("User #{name} with old user id #{old_user_id} is deleted, skipping.")
elsif (user = User.find_by(email:, organisation:))
is_dpo = user.is_data_protection_officer? || is_dpo?(user_field_value(xml_document, "user-type"))
role = highest_role(user.role, role(user_field_value(xml_document, "user-type")))
user.update!(role:, is_dpo:)
user.legacy_users.create!(old_user_id:)
else
user = User.new
user.email = email
user.name = name
user.password = Devise.friendly_token
user.phone = user_field_value(xml_document, "telephone-no")
user.organisation = organisation
user.role = role(user_field_value(xml_document, "user-type"))
user.is_dpo = is_dpo?(user_field_value(xml_document, "user-type"))
user.is_key_contact = is_key_contact?(user_field_value(xml_document, "contact-priority-id"))
user.active = user_field_value(xml_document, "active")
user.skip_confirmation_notification!
begin
user.save!
user.legacy_users.create!(old_user_id:)
user
rescue ActiveRecord::RecordInvalid => e
@logger.error(e.message)
@logger.error("Could not save user with email: #{email}")
end
end
end
def create_user_who_signed_dpc(xml_document)
dpc_signer_name = field_value(dataprotect_xml, "dataprotect", "dp-user")
name = user_field_value(xml_document, "full-name")
if name == dpc_signer_name && is_dpo?(user_field_value(xml_document, "user-type"))
create_user(xml_document)
end
end
def user_field_value(xml_document, field)
field_value(xml_document, "user", field, { "user" => "dclg:user" })
end
def role(field_value)
return unless field_value
{
"co-ordinator" => "data_coordinator",
"data provider" => "data_provider",
"private data downloader" => "data_accessor",
}[field_value.downcase.strip]
end
def highest_role(role_a, role_b)
return unless role_a || role_b
return role_a unless role_b
return role_b unless role_a
[role_a, role_b].map(&:to_sym).sort! { |a, b| User::ROLES[b] <=> User::ROLES[a] }.first
end
def is_dpo?(field_value)
return false if field_value.blank?
field_value.downcase.strip == "data protection officer"
end
def is_key_contact?(field_value)
return false if field_value.blank?
["ecore contact", "key performance contact"].include?(field_value.downcase.strip)
end
end
end

4
lib/tasks/blank_migrated_soctenant_values.rake

@ -1,4 +0,0 @@
desc "Alter soctenant values for sales logs in the database if the subsequent questions are blank or inferred as don't know"
task blank_migrated_soctenant_values: :environment do
SalesLog.imported.filter_by_year(2023).where(frombeds: nil, fromprop: 0, socprevten: 10, soctenant: 0).update_all(soctenant: nil, fromprop: nil, socprevten: nil, values_updated_at: Time.zone.now)
end

14
lib/tasks/confirm_charges_soft_validations.rake

@ -1,14 +0,0 @@
desc "Confirms scharge, pscharge and supcharge soft validations for completed logs"
task confirm_charges_soft_validations: :environment do
LettingsLog.where(status: "completed").filter_by_year(2022).each do |log|
log.update!(scharge_value_check: 0, values_updated_at: Time.zone.now) if log.scharge_value_check.blank? && log.scharge_over_soft_max?
log.update!(pscharge_value_check: 0, values_updated_at: Time.zone.now) if log.pscharge_value_check.blank? && log.pscharge_over_soft_max?
log.update!(supcharg_value_check: 0, values_updated_at: Time.zone.now) if log.supcharg_value_check.blank? && log.supcharg_over_soft_max?
end
LettingsLog.where(status: "completed").filter_by_year(2023).each do |log|
log.update!(scharge_value_check: 0, values_updated_at: Time.zone.now) if log.scharge_value_check.blank? && log.scharge_over_soft_max?
log.update!(pscharge_value_check: 0, values_updated_at: Time.zone.now) if log.pscharge_value_check.blank? && log.pscharge_over_soft_max?
log.update!(supcharg_value_check: 0, values_updated_at: Time.zone.now) if log.supcharg_value_check.blank? && log.supcharg_over_soft_max?
end
end

5
lib/tasks/correct_has_other_client_group_values.rake

@ -1,5 +0,0 @@
desc "Update has_other_client_group values for schemes"
task correct_has_other_client_group_values: :environment do
Scheme.where(confirmed: true, secondary_client_group: nil).update_all(has_other_client_group: 0)
Scheme.where(confirmed: true).where.not(secondary_client_group: nil).update_all(has_other_client_group: 1)
end

6
lib/tasks/correct_incref_values.rake

@ -1,6 +0,0 @@
desc "Alter incref values for non imported lettings logs in the database"
task correct_incref_values: :environment do
LettingsLog.where(old_id: nil, net_income_known: 0).update_all(incref: 0, updated_at: Time.zone.now)
LettingsLog.where(old_id: nil, net_income_known: 1).update_all(incref: 2, updated_at: Time.zone.now)
LettingsLog.where(old_id: nil, net_income_known: 2).update_all(incref: 1, updated_at: Time.zone.now)
end

6
lib/tasks/correct_location_admin_district.rake

@ -1,6 +0,0 @@
desc "Infers location admin district for locations from location code where it's missing"
task correct_location_admin_district: :environment do
Location.where.not(location_code: nil).where(location_admin_district: nil).each do |location|
location.update(location_admin_district: LocalAuthority.all.active(Time.zone.today).england.find_by(code: location.location_code)&.name)
end
end

10
lib/tasks/correct_min_age_values.rake

@ -1,10 +0,0 @@
desc "Alter age values from 0 to 1"
task correct_min_age_values: :environment do
LettingsLog.where(age2: 0).update_all(age2: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age3: 0).update_all(age3: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age4: 0).update_all(age4: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age5: 0).update_all(age5: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age6: 0).update_all(age6: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age7: 0).update_all(age7: 1, values_updated_at: Time.zone.now)
LettingsLog.where(age8: 0).update_all(age8: 1, values_updated_at: Time.zone.now)
end

6
lib/tasks/correct_ppcodenk_values.rake

@ -1,6 +0,0 @@
desc "Alter ppcodenk values for non imported lettings logs in the database"
task correct_ppcodenk_values: :environment do
LettingsLog.where.not(ppcodenk: nil).find_each do |log|
log.update_columns(ppcodenk: log.ppcodenk == 1 ? 0 : 1)
end
end

31
lib/tasks/data_import.rake

@ -1,31 +0,0 @@
namespace :core do
desc "Import data XMLs from legacy CORE"
task :data_import, %i[type path] => :environment do |_task, args|
type = args[:type]
path = args[:path]
raise "Usage: rake core:data_import['data_type', 'path/to/xml_files']" if path.blank? || type.blank?
storage_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
case type
when "organisation"
Imports::OrganisationImportService.new(storage_service).create_organisations(path)
when "scheme"
Imports::SchemeImportService.new(storage_service).create_schemes(path)
when "scheme-location"
Imports::SchemeLocationImportService.new(storage_service).create_scheme_locations(path)
when "user"
Imports::UserImportService.new(storage_service).create_users(path)
when "data-protection-confirmation"
Imports::DataProtectionConfirmationImportService.new(storage_service).create_data_protection_confirmations(path)
when "organisation-rent-periods"
Imports::OrganisationRentPeriodImportService.new(storage_service).create_organisation_rent_periods(path)
when "lettings-logs"
Imports::LettingsLogsImportService.new(storage_service).create_logs(path)
when "sales-logs"
Imports::SalesLogsImportService.new(storage_service).create_logs(path)
else
raise "Type #{type} is not supported by data_import"
end
end
end

45
lib/tasks/data_import_field.rake

@ -1,45 +0,0 @@
namespace :core do
desc "Update lettings log database field from data XMLs provided by Softwire"
task :lettings_data_import_field, %i[field path] => :environment do |_task, args|
field = args[:field]
path = args[:path]
raise "Usage: rake core:lettings_data_import_field['field','path/to/xml_files']" if path.blank? || field.blank?
# We only allow a reduced list of known fields to be updatable
case field
when "tenancycode", "major_repairs", "lettings_allocation", "offered", "address", "reason", "homeless", "created_by", "sex_and_relat", "general_needs_referral", "person_details", "childrens_care_referral", "old_form_id", "postcode_full"
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
archive_io = s3_service.get_file_io(path)
archive_service = Storage::ArchiveService.new(archive_io)
if archive_service.folder_present?("logs")
Rails.logger.info("Start importing field from folder logs")
Imports::LettingsLogsFieldImportService.new(archive_service).update_field(field, "logs")
Rails.logger.info("Imported")
end
else
raise "Field #{field} cannot be updated by lettings_data_import_field"
end
end
desc "Update sales log database field from data XMLs provided by Softwire"
task :sales_data_import_field, %i[field path] => :environment do |_task, args|
field = args[:field]
path = args[:path]
raise "Usage: rake core:sales_data_import_field['field','path/to/xml_files']" if path.blank? || field.blank?
# We only allow a reduced list of known fields to be updatable
case field
when "owning_organisation_id", "old_form_id", "created_by"
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
archive_io = s3_service.get_file_io(path)
archive_service = Storage::ArchiveService.new(archive_io)
if archive_service.folder_present?("logs")
Rails.logger.info("Start importing field from folder logs")
Imports::SalesLogsFieldImportService.new(archive_service).update_field(field, "logs")
Rails.logger.info("Imported")
end
else
raise "Field #{field} cannot be updated by sales_data_import_field"
end
end
end

175
lib/tasks/full_import.rake

@ -1,175 +0,0 @@
Import = Struct.new("Import", :import_class, :import_method, :folder, :logger)
namespace :import do
desc "Run initial import steps - orgs, schemes, users etc (without triggering user invite emails)"
task :initial, %i[institutions_csv_name] => :environment do |_task, args|
institutions_csv_name = args[:institutions_csv_name]
raise "Usage: rake import:initial['institutions_csv_name']" if institutions_csv_name.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
csv = CSV.parse(s3_service.get_file_io(institutions_csv_name), headers: true)
logs_string = StringIO.new
logger = MultiLogger.new(Logger.new(logs_string))
org_count = csv.length
initial_import_list = [
Import.new(Imports::OrganisationImportService, :create_organisations, "institution", logger),
Import.new(Imports::SchemeImportService, :create_schemes, "mgmtgroups", logger),
Import.new(Imports::SchemeLocationImportService, :create_scheme_locations, "schemes", logger),
Import.new(Imports::UserImportService, :create_users, "user", logger),
Import.new(Imports::DataProtectionConfirmationImportService, :create_data_protection_confirmations, "dataprotect", logger),
Import.new(Imports::OrganisationRentPeriodImportService, :create_organisation_rent_periods, "rent-period", logger),
]
logger.info("Beginning initial imports for #{org_count} organisations")
csv.each do |row|
archive_path = row[1]
archive_io = s3_service.get_file_io(archive_path)
archive_service = Storage::ArchiveService.new(archive_io)
logger.info("Performing initial imports for organisation #{row[0]}")
initial_import_list.each do |step|
if archive_service.folder_present?(step.folder)
step.import_class.new(archive_service, step.logger).send(step.import_method, step.folder)
end
end
log_file = "#{File.basename(institutions_csv_name, File.extname(institutions_csv_name))}_#{File.basename(archive_path, File.extname(archive_path))}_initial.log"
s3_service.write_file(log_file, logs_string.string) if logs_string.string.present?
logs_string.rewind
logs_string.truncate(0)
end
logger.info("Finished initial imports")
end
desc "Specific subset of object imports for washup batch 2"
task :washup_imports, %i[institutions_csv_name] => :environment do |_task, args|
institutions_csv_name = args[:institutions_csv_name]
raise "Usage: rake import:washup_imports['institutions_csv_name']" if institutions_csv_name.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
csv = CSV.parse(s3_service.get_file_io(institutions_csv_name), headers: true)
logs_string = StringIO.new
logger = MultiLogger.new(Logger.new(logs_string))
org_count = csv.length
initial_import_list = [
Import.new(Imports::OrganisationImportService, :create_organisations, "institution", logger),
Import.new(Imports::UserImportService, :create_users_who_signed_dpcs, "user", logger),
Import.new(Imports::DataProtectionConfirmationImportService, :create_data_protection_confirmations, "dataprotect", logger),
Import.new(Imports::OrganisationRentPeriodImportService, :create_organisation_rent_periods, "rent-period", logger),
]
logger.info("Beginning imports for #{org_count} organisations")
csv.each do |row|
archive_path = row[1]
archive_io = s3_service.get_file_io(archive_path)
archive_service = Storage::ArchiveService.new(archive_io)
logger.info("Performing imports for organisation #{row[0]}")
initial_import_list.each do |step|
if archive_service.folder_present?(step.folder)
step.import_class.new(archive_service, step.logger).send(step.import_method, step.folder)
end
end
log_file = "#{File.basename(institutions_csv_name, File.extname(institutions_csv_name))}_#{File.basename(archive_path, File.extname(archive_path))}_initial.log"
s3_service.write_file(log_file, logs_string.string) if logs_string.string.present?
logs_string.rewind
logs_string.truncate(0)
end
logger.info("Finished washup imports")
end
desc "Run logs import steps"
task :logs, %i[institutions_csv_name] => :environment do |_task, args|
institutions_csv_name = args[:institutions_csv_name]
raise "Usage: rake import:logs['institutions_csv_name']" if institutions_csv_name.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
csv = CSV.parse(s3_service.get_file_io(institutions_csv_name), headers: true)
org_count = csv.length
logs_string = StringIO.new
logger = MultiLogger.new(Logger.new(logs_string))
logs_import_list = [
Import.new(Imports::LettingsLogsImportService, :create_logs, "logs", logger),
Import.new(Imports::SalesLogsImportService, :create_logs, "logs", logger),
]
logger.info("Beginning log imports for #{org_count} organisations")
csv.each do |row|
archive_path = row[1]
archive_io = s3_service.get_file_io(archive_path)
archive_service = Storage::ArchiveService.new(archive_io)
log_count = row[2].to_i + row[3].to_i + row[4].to_i + row[5].to_i
logger.info("Importing logs for organisation #{row[0]}, expecting #{log_count} logs")
logs_import_list.each do |step|
if archive_service.folder_present?(step.folder)
step.import_class.new(archive_service, step.logger).send(step.import_method, step.folder)
end
end
log_file = "#{File.basename(institutions_csv_name, File.extname(institutions_csv_name))}_#{File.basename(archive_path, File.extname(archive_path))}_logs.log"
s3_service.write_file(log_file, logs_string.string) if logs_string.string.present?
logs_string.rewind
logs_string.truncate(0)
end
logger.info("Log import complete")
end
desc "Trigger invite emails for imported users"
task :trigger_invites, %i[institutions_csv_name] => :environment do |_task, args|
institutions_csv_name = args[:institutions_csv_name]
raise "Usage: rake import:trigger_invites['institutions_csv_name']" if institutions_csv_name.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
csv = CSV.parse(s3_service.get_file_io(institutions_csv_name), headers: true)
Rails.logger.info("Triggering user invite emails")
csv.each do |row|
organisation = Organisation.find_by(name: row[0])
next unless organisation
users = User.where(organisation:, active: true, initial_confirmation_sent: nil)
users.each { |user| ResendInvitationMailer.resend_invitation_email(user).deliver_later }
end
Rails.logger.info("Invite emails triggered")
end
desc "Generate migrated logs report"
task :generate_reports, %i[institutions_csv_name] => :environment do |_task, args|
institutions_csv_name = args[:institutions_csv_name]
raise "Usage: rake import:generate_reports['institutions_csv_name']" if institutions_csv_name.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
institutions_csv = CSV.parse(s3_service.get_file_io(institutions_csv_name), headers: true)
Imports::ImportReportService.new(s3_service, institutions_csv).create_reports(institutions_csv_name)
end
desc "Generate missing answers report"
task :generate_missing_answers_report, %i[file_suffix] => :environment do |_task, args|
file_suffix = args[:file_suffix]
raise "Usage: rake import:generate_reports['file_suffix']" if file_suffix.blank?
s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
Imports::ImportReportService.new(s3_service, nil).generate_missing_answers_report(file_suffix)
end
desc "Run import from logs step to end"
task :logs_onwards, %i[institutions_csv_name] => %i[environment logs trigger_invites generate_reports]
desc "Run a full import for the institutions listed in the named file on s3"
task :full, %i[institutions_csv_name] => %i[environment initial logs trigger_invites generate_reports]
end

18
lib/tasks/recalculate_irproduct_values.rake

@ -1,18 +0,0 @@
desc "Forces to recalculate irproduct values"
task recalculate_irproduct_values: :environment do
LettingsLog.exportable.where(rent_type: [3, 4, 5]).where(irproduct: nil).each do |log| # irproduct was never set
Rails.logger.info("Could not update irproduct for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where(rent_type: 3).where.not(irproduct: 1).each do |log| # irproduct was set wrong
Rails.logger.info("Could not update irproduct for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where(rent_type: 4).where.not(irproduct: 2).each do |log| # irproduct was set wrong
Rails.logger.info("Could not update irproduct for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where(rent_type: 5).where.not(irproduct: 3).each do |log| # irproduct was set wrong
Rails.logger.info("Could not update irproduct for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where.not(rent_type: [3, 4, 5]).where.not(irproduct: nil).each do |log| # irproduct was set when it should have been nil
Rails.logger.info("Could not update irproduct for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
end

13
lib/tasks/recalculate_lar_values.rake

@ -1,13 +0,0 @@
desc "Forces to recalculate lar values for affordable rent types and clears irrelevant lar values"
task recalculate_lar_values: :environment do
LettingsLog.exportable.where(rent_type: [1, 2], lar: nil).each do |log| # lar was never set
Rails.logger.info("Could not update lar for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where(rent_type: 1).where.not(lar: 2).each do |log| # lar was set wrong
Rails.logger.info("Could not update lar for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where(rent_type: 2).where.not(lar: 1).each do |log| # lar was set wrong
Rails.logger.info("Could not update lar for LettingsLog #{log.id}") unless log.update(values_updated_at: Time.zone.now)
end
LettingsLog.exportable.where.not(rent_type: [1, 2]).where.not(lar: nil).update_all(lar: nil) # lar was set to 2 but should never have been set
end

12
lib/tasks/recalculate_refused_values.rake

@ -1,12 +0,0 @@
desc "Forces to recalculate refused values for lettings logs with unknown person details"
task recalculate_refused_values: :environment do
LettingsLog.exportable.where('details_known_2 = 1
OR details_known_3 = 1
OR details_known_4 = 1
OR details_known_5 = 1
OR details_known_6 = 1
OR details_known_7 = 1
OR details_known_8 = 1').each do |log|
log.update!(values_updated_at: Time.zone.now)
end
end

22
lib/tasks/remove_placeholder_deactivations.rake

@ -1,22 +0,0 @@
namespace :data_cleanup do
desc "Remove all the deactivations for given model with deactivation date after 2031/01/01"
task :remove_placeholder_deactivations, %i[model_name] => :environment do |_task, args|
model_name = args[:model_name]
raise "Usage: rake data_cleanup:remove_placeholder_deactivations['model_name']" if model_name.blank?
case model_name
when "location"
location_deactivation_periods = LocationDeactivationPeriod.where("deactivation_date >= ?", Time.zone.local(2031, 1, 1))
location_deactivation_periods_count = location_deactivation_periods.count
location_deactivation_periods.delete_all
Rails.logger.info("Removed #{location_deactivation_periods_count} location deactivation periods")
when "scheme"
scheme_deactivation_periods = SchemeDeactivationPeriod.where("deactivation_date >= ?", Time.zone.local(2031, 1, 1))
scheme_deactivation_periods_count = scheme_deactivation_periods.count
scheme_deactivation_periods.delete_all
Rails.logger.info("Removed #{scheme_deactivation_periods_count} scheme deactivation periods")
else
raise "Deactivations for #{model_name} cannot be deleted"
end
end
end

35
lib/tasks/squish_names.rake

@ -1,35 +0,0 @@
desc "Squish names of locations, schemes, users, and organisations"
task squish_names: :environment do
Location.where("name LIKE ?", "% %").each do |location|
location.name&.squish!
begin
location.save!
rescue StandardError => e
Sentry.capture_exception(e)
end
end
Scheme.where("service_name LIKE ?", "% %").each do |scheme|
scheme.service_name&.squish!
begin
scheme.save!
rescue StandardError => e
Sentry.capture_exception(e)
end
end
User.where("name LIKE ?", "% %").each do |user|
user.name&.squish!
begin
user.save!
rescue StandardError => e
Sentry.capture_exception(e)
end
end
Organisation.where("name LIKE ?", "% %").each do |organisation|
organisation.name&.squish!
begin
organisation.save!
rescue StandardError => e
Sentry.capture_exception(e)
end
end
end

11
lib/tasks/sync_legacy_users.rake

@ -1,11 +0,0 @@
namespace :core do
# TODO: Remove once ran on all environments.
desc "Creates a LegacyUser object for any existing Users"
task sync_legacy_users: :environment do
User.where.not(old_user_id: nil).includes(:legacy_users).find_each do |user|
next if user.legacy_users.where(old_user_id: user.old_user_id).any?
user.legacy_users.create!(old_user_id: user.old_user_id)
end
end
end

16
spec/fixtures/files/imported_lettings_logs_missing_answers_examples.csv vendored

@ -1,16 +0,0 @@
Missing answers,Organisation ID,Log ID,Old Form ID,Old Log ID
age1_known,{org_id0},{id0},1000,old_id_age1_known_0
age1_known,{org_id1},{id1},1001,old_id_age1_known_1
age1_known,{org_id2},{id2},1002,old_id_age1_known_2
age1_known,{org_id3},{id3},1003,old_id_age1_known_3
age1_known,{org_id4},{id4},1004,old_id_age1_known_4
age1_known,{org_id5},{id5},1005,old_id_age1_known_5
age1_known,{org_id6},{id6},1006,old_id_age1_known_6
age1_known,{org_id7},{id7},1007,old_id_age1_known_7
age1_known,{org_id8},{id8},1008,old_id_age1_known_8
age1_known,{org_id9},{id9},1009,old_id_age1_known_9
beds,{org_id2_0},{id2_0},2000,old_id_beds_0
beds,{org_id2_1},{id2_1},2001,old_id_beds_1
beds,{org_id2_2},{id2_2},2002,old_id_beds_2
beds,{org_id2_3},{id2_3},2003,old_id_beds_3
"beds, age1_known",{org_id},{id},300,beds_and_age
1 Missing answers Organisation ID Log ID Old Form ID Old Log ID
2 age1_known {org_id0} {id0} 1000 old_id_age1_known_0
3 age1_known {org_id1} {id1} 1001 old_id_age1_known_1
4 age1_known {org_id2} {id2} 1002 old_id_age1_known_2
5 age1_known {org_id3} {id3} 1003 old_id_age1_known_3
6 age1_known {org_id4} {id4} 1004 old_id_age1_known_4
7 age1_known {org_id5} {id5} 1005 old_id_age1_known_5
8 age1_known {org_id6} {id6} 1006 old_id_age1_known_6
9 age1_known {org_id7} {id7} 1007 old_id_age1_known_7
10 age1_known {org_id8} {id8} 1008 old_id_age1_known_8
11 age1_known {org_id9} {id9} 1009 old_id_age1_known_9
12 beds {org_id2_0} {id2_0} 2000 old_id_beds_0
13 beds {org_id2_1} {id2_1} 2001 old_id_beds_1
14 beds {org_id2_2} {id2_2} 2002 old_id_beds_2
15 beds {org_id2_3} {id2_3} 2003 old_id_beds_3
16 beds, age1_known {org_id} {id} 300 beds_and_age

4
spec/fixtures/files/imported_lettings_logs_missing_answers_report.csv vendored

@ -1,4 +0,0 @@
Missing answers,Total number of affected logs
age1_known,10
beds,4
"beds, age1_known",1
1 Missing answers Total number of affected logs
2 age1_known 10
3 beds 4
4 beds, age1_known 1

7
spec/fixtures/imports/dataprotect/7c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml vendored

@ -1,7 +0,0 @@
<dataprotect:dataprotect xmlns:dataprotect="dclg:dataprotect">
<dataprotect:id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</dataprotect:id>
<dataprotect:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</dataprotect:institution>
<dataprotect:data-protection>true</dataprotect:data-protection>
<dataprotect:dp-user>John Doe</dataprotect:dp-user>
<dataprotect:change-date>05/06/2018 10:36:49:34</dataprotect:change-date>
</dataprotect:dataprotect>

23
spec/fixtures/imports/institution/7c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml vendored

@ -1,23 +0,0 @@
<institution:institution xmlns:institution="dclg:institution">
<institution:id>7c5bd5fb549c09z2c55d9cb90d7ba84927e64618</institution:id>
<institution:name>HA Ltd</institution:name>
<institution:institution-type>HOUSING-ASSOCIATION</institution:institution-type>
<institution:active>true</institution:active>
<institution:almsyn>false</institution:almsyn>
<institution:old-association-type>CHHA</institution:old-association-type>
<institution:telephone-number>xxxxxxxx</institution:telephone-number>
<institution:software-supplier-id>false</institution:software-supplier-id>
<institution:housing-management-system/>
<institution:choice-based-letting>false</institution:choice-based-letting>
<institution:common-housing-register>false</institution:common-housing-register>
<institution:choice-allocation-policy>false</institution:choice-allocation-policy>
<institution:cbl-proportion-percentage/>
<institution:enter-affordable-logs>true</institution:enter-affordable-logs>
<institution:owns-affordable-rent>true</institution:owns-affordable-rent>
<institution:housing-registration-no>LH9999</institution:housing-registration-no>
<institution:visible-id>1034</institution:visible-id>
<institution:holds-stock>true</institution:holds-stock>
<institution:general-needs-units>1104</institution:general-needs-units>
<institution:supported-housing-units>217</institution:supported-housing-units>
<institution:unspecified-units>0</institution:unspecified-units>
</institution:institution>

23
spec/fixtures/imports/institution/8c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml vendored

@ -1,23 +0,0 @@
<institution xmlns="dclg:institution">
<id>8c5bd5fb549c09z2c55d9cb90d7ba84927e64618</id>
<name>HA Ltd</name>
<institution-type>HOUSING-ASSOCIATION</institution-type>
<active>true</active>
<almsyn>false</almsyn>
<old-association-type>CHHA</old-association-type>
<telephone-number>xxxxxxxx</telephone-number>
<software-supplier-id>false</software-supplier-id>
<housing-management-system/>
<choice-based-letting>false</choice-based-letting>
<common-housing-register>false</common-housing-register>
<choice-allocation-policy>false</choice-allocation-policy>
<cbl-proportion-percentage/>
<enter-affordable-logs>true</enter-affordable-logs>
<owns-affordable-rent>true</owns-affordable-rent>
<housing-registration-no>LH9999</housing-registration-no>
<visible-id>1034</visible-id>
<holds-stock>true</holds-stock>
<general-needs-units>1104</general-needs-units>
<supported-housing-units>217</supported-housing-units>
<unspecified-units>0</unspecified-units>
</institution>

515
spec/fixtures/imports/logs/00d2343e-d5fa-4c89-8400-ec3854b0f2b4.xml vendored

@ -1,515 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-SR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-SR-GN</meta:form-name>
<meta:document-id>00d2343e-d5fa-4c89-8400-ec3854b0f2b4</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09z2c55d9cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-04-14T16:01:30.369241Z</meta:created-date>
<meta:modified-date>2022-04-14T16:01:30.369241Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<Group>
<renewal/>
<KeyDate>2022-04-14</KeyDate>
<FORM>5985624</FORM>
<Landlord source-value="1">1 Private Registered Provider</Landlord>
<_2bTenCode>600009258</_2bTenCode>
<Q21a/>
</Group>
</Group>
<Group>
<P1Age override-field="">52</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>10) Person prefers not to say</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age override-field=""/>
<P2AR/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
</Group>
<Group>
<Q12c>6 Don&#x2019;t Know</Q12c>
<Q12d>6 Don&#x2019;t Know</Q12d>
<Q9a>19 To move to independent accommodation</Q9a>
<Q9aa/>
<Q11 override-field="">28 Living with friends or family</Q11>
<Q13>1 No</Q13>
<Q12b override-field="">SR2 8SW</Q12b>
<Q12bnot/>
<Q12a>Sunderland</Q12a>
<Q12aONS>E08000024</Q12aONS>
<Q14a>3 Don&#x2019;t know</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
<Q15CBL>1 Yes</Q15CBL>
<Q15CHR>2 No</Q15CHR>
<Q15CAP>2 No</Q15CAP>
<Group>
<Q16>2 Tenant applied direct (no referral or nomination)</Q16>
</Group>
</Group>
<Group>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
</Group>
<Group>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g/>
<Q10-h>Yes</Q10-h>
<Q10ia>3 Tenant prefers not to say</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3/>
<Q10ib-4/>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
</Group>
<Group/>
<Group/>
<Group/>
</Group>
<Group>
<joint>2 No</joint>
<_2a>1 Yes</_2a>
<Q2b>2 Assured &#x2013; lifetime</Q2b>
<Q2ba/>
<_2cYears/>
</Group>
<Group>
<UPRN>12345678</UPRN>
<AddressLine1/>
<AddressLine2/>
<TownCity/>
<County/>
<Q28pc override-field="">SR8 3HF</Q28pc>
<Q28Auth>Durham</Q28Auth>
<Q28ONS>E06000047</Q28ONS>
<Q28same/>
<firstsoc/>
<Q27>15 First let of newbuild property</Q27>
<Q20 override-field="">1</Q20>
<Q26/>
<Q23>7 House</Q23>
<Q24>1 Purpose built</Q24>
<Q25>2 No</Q25>
<Q22 override-field="">2</Q22>
<Q19void>2022-04-14</Q19void>
<Q19repair/>
</Group>
<Group>
<CombinedInc>3 Don&#x2019;t know</CombinedInc>
<Q8Refused>Refused</Q8Refused>
<Q8Money override-field=""/>
<Q8a/>
<Q6Ben>3 Don&#x2019;t know</Q6Ben>
<Q7Ben>4 Don&#x2019;t Know</Q7Ben>
<Q17>7 Weekly for 48 weeks</Q17>
<Q18ai override-field="">106.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field=""/>
<Q18av override-field="">106.00</Q18av>
<Q18d/>
<Q18dyes override-field=""/>
</Group>
<Group>
<F1Age>0</F1Age>
<F2Age>0</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>0</FAge>
<F1>1</F1>
<F2>0</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>1</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>0</P170>
<P270>0</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>0</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>0</P1FT>
<P2FT>0</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>0</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<Q1bV1/>
<Q1bV2/>
<Q1bV3/>
<Q1bVT>0</Q1bVT>
<P1Adult>1</P1Adult>
<P2Adult>0</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>1</PAdultT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>52</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>52</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>52</AgeDiff3>
<TODAY>2022-04-14Z</TODAY>
<FutureLimit>2022-04-29Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>0</Q10gv>
<Q10hv>20</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>C</Q2bv>
<P2Agev>0</P2Agev>
<P2Sexv>0</P2Sexv>
<P2Relv>0</P2Relv>
<P2Ecov>0</P2Ecov>
<P2valid>0</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<TOTADULT>1</TOTADULT>
<NEW_OLD>1 New Tenant</NEW_OLD>
<Q18aValid>1</Q18aValid>
<Q18Valid>1</Q18Valid>
<VACDAYS>0</VACDAYS>
<HHMEMB>1</HHMEMB>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<HHTYPE>3 = 1 adult</HHTYPE>
<WEEKLYINC/>
<INCOME/>
<TYPEHB>3</TYPEHB>
<AFFRATE/>
<Weekinc/>
<LETTYPE>1 Private Registered Provider</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000001</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>655</HCNUM>
<MANHCNUM>655</MANHCNUM>
<LAHA/>
<MANINGORGID>2</MANINGORGID>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3>3</HBTYPE3>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13>13</HBTYPE13>
<HBTYPE14/>
<HBTYPE15/>
<HBTYPE>3</HBTYPE>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WRENT>97.85</WRENT>
<WTCHARGE>97.85</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG/>
<ChildBen>0.00</ChildBen>
<WTSHORTFALL1/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT1>97.85</WRENT1>
<WTCHARGE1>97.85</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1/>
<ChildBen1>0</ChildBen1>
</Group>
<Group>
<BSa>0</BSa>
<BSb>1</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>1</BEDROOMSTAND>
<BEDMINUSBEDS>1</BEDMINUSBEDS>
<WRENTreduced>84.15</WRENTreduced>
<NonDepDeduct>0</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>77</PrsnlAllowan>
<HousBenDisAl>5</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>0</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>14</DAY>
<MONTH>4</MONTH>
<YEAR>2022</YEAR>
<VDAY>14</VDAY>
<VMONTH>4</VMONTH>
<VYEAR>2022</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>SR2</PPOSTC1>
<PPOSTC2>8SW</PPOSTC2>
<POSTCODE/>
<POSTCOD2/>
</Group>
</Group>

524
spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml vendored

@ -1,524 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-SR-SH" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-SR-SH</meta:form-name>
<meta:document-id>0b4a68df-30cc-474a-93c0-a56ce8fdad3b</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09z2c55d9cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-01-05T12:50:20.39153Z</meta:created-date>
<meta:modified-date>2022-01-05T12:50:20.39153Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<KeyDate>2021-11-05</KeyDate>
<FORM>123456</FORM>
<Landlord source-value="2">2 Local Authority</Landlord>
<Group>
<_1cmangroupcode>0123</_1cmangroupcode>
<_1cschemecode>10</_1cschemecode>
<schPC/>
<Q1e>3 No</Q1e>
</Group>
</Group>
<Group>
<_2a>2 No</_2a>
<Q2b>1 Secure (inc flexible)</Q2b>
<Q2ba/>
<_2bTenCode>14044912001</_2bTenCode>
<_2cYears>2</_2cYears>
</Group>
<Group>
<P1Age override-field="">72</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>5) Retired</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field="">74</P2Age>
<P2AR/>
<P2Sex override-field="">Male</P2Sex>
<P2Rel>Partner</P2Rel>
<P2Eco>5) Retired</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>9 Not in receipt of either UC or HB</Q6Ben>
</Group>
<Group>
<Q7Ben>2 Some</Q7Ben>
<Q8Refused>Refused</Q8Refused>
<Q8Money override-field=""/>
<Q8a/>
</Group>
<Group>
<Q9a>13 Property unsuitable because of ill health / disability</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>1 Yes</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3>Yes</Q10ib-3>
<Q10ib-4/>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">26 Owner occupation (private)</Q11>
<Q12a>DLUHC</Q12a>
<Q12aONS>E08000035</Q12aONS>
<Q12b override-field="">S80 4DJ</Q12b>
<Q12bnot/>
<Q12c>5 5 years or more</Q12c>
<Q12d>9 3 years but under 4 years</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>2 No</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>1 Yes</Q15CBL>
<Q15CHR>1 Yes</Q15CHR>
<Q15CAP>1 Yes</Q15CAP>
</Group>
<Group>
<Q16>2 Tenant applied direct (no referral or nomination)</Q16>
</Group>
</Group>
<Group>
<Q17>7 Weekly for 48 weeks</Q17>
<Q18ai override-field="true">125.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field="">7.00</Q18aiv>
<Q18av override-field="">132.00</Q18av>
<Q18b override-field=""/>
<Q18c/>
<Q18d/>
<Q18dyes override-field=""/>
<Q19void>2021-08-24</Q19void>
<Q19repair/>
<Q19supsch/>
<Q20 override-field="">0</Q20>
<Q21a>14044912</Q21a>
</Group>
<Group>
<Q25>1 Yes</Q25>
<Q27>15 First let of newbuild property</Q27>
</Group>
<Group>
<F1Age>0</F1Age>
<F2Age>0</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>0</FAge>
<F1>1</F1>
<F2>0</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>1</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>1</P170>
<P270>1</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>1</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>0</P1FT>
<P2FT>0</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>0</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>1</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>1</Partner>
<Q1cV1>1</Q1cV1>
<Q1cV2>1</Q1cV2>
<Q1cVT>2</Q1cVT>
<P1Adult>1</P1Adult>
<P2Adult>1</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>2</PAdultT>
<P2PAge>74</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>74</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>72</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>74</AgeDiff3>
<TODAY>2022-01-05Z</TODAY>
<FutureLimit>2022-01-20Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>A</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<ChildBen>0.00</ChildBen>
<TOTADULT>2</TOTADULT>
<NEW_OLD>1 New Tenant</NEW_OLD>
<WCHCHRG/>
<VACDAYS>73</VACDAYS>
<HHMEMB>2</HHMEMB>
<HHTYPEP1A>0</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>0</TADULT>
<HHTYPEP1E>1</HHTYPEP1E>
<HHTYPEP2E>1</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>2</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q18aValid>1</Q18aValid>
<Q18bValid>0</Q18bValid>
<Q18cValid>0</Q18cValid>
<Q18Valid>1</Q18Valid>
<HHTYPE>2 = 2 Adults at least one is an Elder</HHTYPE>
<WEEKLYINC/>
<INCOME/>
<TYPEHB>15.00</TYPEHB>
<AFFRATE/>
<Weekinc/>
<LETTYPE>2 Local Authority</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000004</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>N/A</HCNUM>
<MANHCNUM>N/A</MANHCNUM>
<LAHA/>
<MANINGORGID>2</MANINGORGID>
<Q28same1>false</Q28same1>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13/>
<HBTYPE14/>
<HBTYPE15>15</HBTYPE15>
<HBTYPE>15</HBTYPE>
<SCHEME>000001005048</SCHEME>
<MANTYPE>D</MANTYPE>
<UNITS>15</UNITS>
<UNITTYPE>6</UNITTYPE>
<SCHTYPE>7</SCHTYPE>
<REGHOME>1</REGHOME>
<SUPPORT>2</SUPPORT>
<MOBSTAND>A</MOBSTAND>
<INTSTAY>P</INTSTAY>
<CLIGRP1>M</CLIGRP1>
<CLIGRP2/>
<Q28Auth>DLUHC</Q28Auth>
<Q28ONS>E08000035</Q28ONS>
<Q28pc override-field="">S80 4QE</Q28pc>
<Q28same/>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT>115.38</WRENT>
<WTCHARGE>121.85</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG>6.46</WSUPCHRG>
<WTSHORTFALL1/>
<WRENT1>115.38</WRENT1>
<WTCHARGE1>121.85</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1>6.46</WSUPCHRG1>
</Group>
<Group>
<BSa>1</BSa>
<BSb>0</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>1</BEDROOMSTAND>
<BEDMINUSBEDS/>
<WRENTreduced>115.38</WRENTreduced>
<NonDepDeduct>0</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>117.4</PrsnlAllowan>
<HousBenDisAl>10</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>0</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>5</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>24</VDAY>
<VMONTH>8</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>LS16</PPOSTC1>
<PPOSTC2>6FT</PPOSTC2>
<POSTCODE>LS16</POSTCODE>
<POSTCOD2>6FT</POSTCOD2>
</Group>
</Group>

533
spec/fixtures/imports/logs/0ead17cb-1668-442d-898c-0d52879ff592.xml vendored

@ -1,533 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-SR-GN"
xmlns:app="http://www.w3.org/2007/app"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:meta="http://data.gov.uk/core/metadata"
xmlns:svc="http://www.w3.org/2007/app"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/"
xmlns:xqx="http://www.w3.org/2005/XQueryX"
xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-SR-GN</meta:form-name>
<meta:document-id>0ead17cb-1668-442d-898c-0d52879ff592</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa
</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618
</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09z2c55d9cb90d7ba84927e64618
</meta:managing-institution-id>
<meta:created-date>2021-10-08T14:48:17.096123Z</meta:created-date>
<meta:modified-date>2021-10-08T14:48:17.096123Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<KeyDate>2021-09-30</KeyDate>
<FORM>5786509</FORM>
<Landlord source-value="1">1 Private Registered Provider</Landlord>
<Group>
<_1btenagree>1 This Landlord</_1btenagree>
<_1bifanother/>
<_1bCOREcode/>
</Group>
</Group>
<Group>
<_2a>1 Yes</_2a>
<Q2b>2 Assured</Q2b>
<Q2ba/>
<_2bTenCode>MAC003</_2bTenCode>
<_2cYears/>
</Group>
<Group>
<P1Age override-field=""/>
<P1AR>Age_Refused</P1AR>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>6) Not Seeking Work</P1Eco>
<P1Eth>17 Refused</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field=""/>
<P2AR>Age_Refused</P2AR>
<P2Sex override-field="">Male</P2Sex>
<P2Rel>Child</P2Rel>
<P2Eco>9) Child under 16</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>6 UC – with housing element (and not in receipt of Housing
Benefit)
</Q6Ben>
</Group>
<Group>
<Q7Ben>1 All</Q7Ben>
<Q8Refused/>
<Q8Money override-field="">600.00</Q8Money>
<Q8a>2 Monthly</Q8a>
</Group>
<Group>
<Q9a>12 Property unsuitable because of overcrowding</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>2 No</Q10ia>
<joint>2 No</joint>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3/>
<Q10ib-4/>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">30 Fixed term Local Authority General Needs
tenancy
</Q11>
<Q12a>Leeds</Q12a>
<Q12aONS>E08000035</Q12aONS>
<Q12b override-field="">LS8 3HX</Q12b>
<Q12bnot/>
<Q12c>5 5 years or more</Q12c>
<Q12d>2 Less than 1 year</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>1 Yes</Q14a>
<Q14b1/>
<Q14b2>2_Living_in_insanitary_or_overcrowded_or_unsatisfactory_housing
</Q14b2>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>1 Yes</Q15CBL>
<Q15CHR>2 No</Q15CHR>
<Q15CAP>2 No</Q15CAP>
</Group>
<Group>
<Q16>3 PRP lettings only - nominated by a local housing authority</Q16>
</Group>
</Group>
<Group>
<Q17>4 Calendar monthly</Q17>
<Q18ai override-field="">406.09</Q18ai>
<Q18aii override-field="">32.02</Q18aii>
<Q18aiii override-field=""/>
<Q18aiv override-field=""/>
<Q18av override-field="">438.11</Q18av>
<Q18d>1 Yes</Q18d>
<Q18dyes override-field="true"/>
<Q19void>2021-09-30</Q19void>
<Q19repair/>
<Q20 override-field="">21</Q20>
<Q21a>MCB003</Q21a>
</Group>
<Group>
<Q22 override-field="">2</Q22>
<Q23>1 Flat / maisonette</Q23>
<Q24>1 Purpose built</Q24>
<Q25>2 No</Q25>
<Q26>4 An Intermediate Rent basis</Q26>
<Q27>10 Relet - tenant evicted due to arrears</Q27>
</Group>
<Group>
<Q28Auth>Leeds</Q28Auth>
<Q28ONS>E08000035</Q28ONS>
<Q28pc override-field="">LS16 6FT</Q28pc>
</Group>
<Group>
<F1Age>1</F1Age>
<F2Age>0</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>1</FAge>
<F1>1</F1>
<F2>0</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>1</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>0</P170>
<P270>0</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>0</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>0</P1FT>
<P2FT>0</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>0</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>1</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>1</Child>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<Q1bV1>0</Q1bV1>
<Q1bV2>0</Q1bV2>
<Q1bV3>1</Q1bV3>
<Q1bVT>1</Q1bVT>
<P1Adult>1</P1Adult>
<P2Adult>0</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>1</PAdultT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>23</PAGE>
<P2ChildAge>2</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>2</ChildAgeMin>
<AgeDiff1>23</AgeDiff1>
<AgeDiff2>21</AgeDiff2>
<AgeDiff3>23</AgeDiff3>
<TODAY>2021-10-08Z</TODAY>
<FutureLimit>2021-10-23Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>C</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>1</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>1</Q14bv>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<ChildBen>21.05</ChildBen>
<TOTADULT>1</TOTADULT>
<NEW_OLD>2 Existing Tenant</NEW_OLD>
<Q18aValid>1</Q18aValid>
<Q18Valid>1</Q18Valid>
<VACDAYS>0</VACDAYS>
<HHMEMB/>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>1</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>1</TCHILD>
<HHTYPE>5 = 1 adult + 1 or more children</HHTYPE>
<WEEKLYINC>133.33</WEEKLYINC>
<INCOME>154.38</INCOME>
<TYPEHB>7.00</TYPEHB>
<AFFRATE/>
<Weekinc>154.38</Weekinc>
<LETTYPE>1 Private Registered Provider</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000003</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>655</HCNUM>
<MANHCNUM>655</MANHCNUM>
<LAHA/>
<MANINGORGID>1</MANINGORGID>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7>7</HBTYPE7>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13/>
<HBTYPE14/>
<HBTYPE15/>
<HBTYPE>7</HBTYPE>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WRENT>93.71</WRENT>
<WTCHARGE>101.10</WTCHARGE>
<WSCHARGE>7.39</WSCHARGE>
<WPSCHRGE/>
<WSUPCHRG/>
<WTSHORTFALL1/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT1>93.71</WRENT1>
<WTCHARGE1>101.10</WTCHARGE1>
<WSCHARGE1>7.39</WSCHARGE1>
<WPSCHRGE1/>
<WSUPCHRG1/>
</Group>
<Group>
<BSa>0</BSa>
<BSb>1</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0.5</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>1</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>1</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>2</BEDROOMSTAND>
<BEDMINUSBEDS>0</BEDMINUSBEDS>
<WRENTreduced>93.71</WRENTreduced>
<NonDepDeduct>0</NonDepDeduct>
<RENTHB/>
<ChildAllowan>68.6</ChildAllowan>
<PrsnlAllowan>74.7</PrsnlAllowan>
<HousBenDisAl>25</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>1</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>0</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>30</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>30</VDAY>
<VMONTH>9</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY>16</MRCDAY>
<MRCMONTH>10</MRCMONTH>
<MRCYEAR>2021</MRCYEAR>
<PPOSTC1>SR7</PPOSTC1>
<PPOSTC2>0A5</PPOSTC2>
<POSTCODE>TS27</POSTCODE>
<POSTCOD2>5B7</POSTCOD2>
</Group>
</Group>

515
spec/fixtures/imports/logs/166fc004-392e-47a8-acb8-1c018734882b.xml vendored

@ -1,515 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-IR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-IR-GN</meta:form-name>
<meta:document-id>166fc004-392e-47a8-acb8-1c018734882b</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-04-12T14:10:59.953121Z</meta:created-date>
<meta:modified-date>2022-04-12T14:10:59.953121Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Bulk Upload</meta:upload-method>
<meta:upload-id>8dda8f1a-f5a1-4827-8d82-dd7fd9258eab</meta:upload-id>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<IRProduct>2 London Living Rent</IRProduct>
<IRProductOther/>
<KeyDate>2021-11-10</KeyDate>
<FORM>300072</FORM>
<Landlord source-value="9">1 Private Registered Provider</Landlord>
<Group>
<_1btenagree>1 This Landlord</_1btenagree>
<_1bifanother/>
<_1bCOREcode/>
</Group>
</Group>
<Group>
<_2a>2 No</_2a>
<Q2b>2 Assured</Q2b>
<Q2ba/>
<_2bTenCode>TEN0021</_2bTenCode>
<_2cYears/>
</Group>
<Group>
<P1Age override-field="">37</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>1) Full Time</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field="">34</P2Age>
<P2AR/>
<P2Sex override-field="">Female</P2Sex>
<P2Rel>Other</P2Rel>
<P2Eco>1) Full Time</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>7 UC &#x2013; without housing element (not in receipt of HB and tenants not eligible for housing support e.g. residential care home)</Q6Ben>
</Group>
<Group>
<Q7Ben>3 None</Q7Ben>
<Q8Refused/>
<Q8Money override-field="">200.00</Q8Money>
<Q8a>1 Weekly</Q8a>
</Group>
<Group>
<Q9a>8 (Non-violent) relationship breakdown with partner</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>1 Yes</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3/>
<Q10ib-4>Yes</Q10ib-4>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">28 Living with friends or family</Q11>
<Q12a>Blackpool</Q12a>
<Q12aONS>E09000009</Q12aONS>
<Q12b override-field="">FY1 1JD</Q12b>
<Q12bnot/>
<Q12c>1 Just moved to Local Authority area</Q12c>
<Q12d>1 Just moved to Local Authority area</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>2 No</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>2 No</Q15CBL>
<Q15CHR>2 No</Q15CHR>
<Q15CAP>1 Yes</Q15CAP>
</Group>
<Group>
<Q16>10 Other social landlord</Q16>
</Group>
</Group>
<Group>
<Q17>1 Weekly for 52 weeks</Q17>
<Q18ai override-field="">100.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field=""/>
<Q18av override-field="">100.00</Q18av>
<Q18d/>
<Q18dyes override-field=""/>
<Q19void>2021-04-15</Q19void>
<Q19repair/>
<Q20 override-field="">0</Q20>
<Q21a>PROPREF0042</Q21a>
</Group>
<Group>
<Q22 override-field="">2</Q22>
<Q23>1 Flat / maisonette</Q23>
<Q24>1 Purpose built</Q24>
<Q25>2 No</Q25>
<Q26>4 An Intermediate Rent basis</Q26>
<Q27>10 Relet - tenant evicted due to arrears</Q27>
</Group>
<Group>
<Q28Auth>Basingstoke &amp; Deane</Q28Auth>
<Q28ONS>E07000084</Q28ONS>
<Q28pc override-field="">RG21 3HU</Q28pc>
</Group>
<Group>
<F1Age>1</F1Age>
<F2Age>1</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>2</FAge>
<F1>1</F1>
<F2>1</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>2</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>0</P170>
<P270>0</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>0</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>1</P1FT>
<P2FT>1</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>2</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<Q1bV1>0</Q1bV1>
<Q1bV2>0</Q1bV2>
<Q1bV3>1</Q1bV3>
<Q1bVT>1</Q1bVT>
<P1Adult>1</P1Adult>
<P2Adult>1</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>2</PAdultT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>37</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>37</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>37</AgeDiff3>
<TODAY>2022-04-12Z</TODAY>
<FutureLimit>2022-04-27Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>C</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>1</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>1</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<TOTADULT>2</TOTADULT>
<NEW_OLD>2 Existing Tenant</NEW_OLD>
<Q18aValid>1</Q18aValid>
<Q18Valid>1</Q18Valid>
<VACDAYS>209</VACDAYS>
<HHMEMB>2</HHMEMB>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>1</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>2</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<HHTYPE>4 = 2 adults</HHTYPE>
<WEEKLYINC>200.00</WEEKLYINC>
<INCOME>200.00</INCOME>
<TYPEHB>13</TYPEHB>
<AFFRATE/>
<Weekinc>200.00</Weekinc>
<LETTYPE>1 Private Registered Provider</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000008</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>655</HCNUM>
<MANHCNUM>655</MANHCNUM>
<LAHA/>
<MANINGORGID>1</MANINGORGID>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13>13</HBTYPE13>
<HBTYPE14/>
<HBTYPE15/>
<HBTYPE>13</HBTYPE>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WRENT>100.00</WRENT>
<WTCHARGE>100.00</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG/>
<ChildBen>0.00</ChildBen>
<WTSHORTFALL1/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT1>100.00</WRENT1>
<WTCHARGE1>100.00</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1/>
<ChildBen1>0</ChildBen1>
</Group>
<Group>
<BSa>0</BSa>
<BSb>2</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>2</BEDROOMSTAND>
<BEDMINUSBEDS>0</BEDMINUSBEDS>
<WRENTreduced>100.00</WRENTreduced>
<NonDepDeduct>23.35</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>0</PrsnlAllowan>
<HousBenDisAl>0</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>23.35</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>10</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>15</VDAY>
<VMONTH>4</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>FY1</PPOSTC1>
<PPOSTC2>1JD</PPOSTC2>
<POSTCODE/>
<POSTCOD2/>
</Group>
</Group>

514
spec/fixtures/imports/logs/5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd.xml vendored

@ -1,514 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-IR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-IR-GN</meta:form-name>
<meta:document-id>5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd</meta:document-id>
<meta:owner-user-id>e29c492473446dca4d50224f2bb7cf965a261d6f</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-04-11T13:46:23.953121Z</meta:created-date>
<meta:modified-date>2022-04-11T13:46:23.953121Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<IRProduct>2 London Living Rent</IRProduct>
<IRProductOther/>
<KeyDate>2021-11-10</KeyDate>
<FORM>300072</FORM>
<Landlord source-value="9">1 Private Registered Provider</Landlord>
<Group>
<_1btenagree>1 This Landlord</_1btenagree>
<_1bifanother/>
<_1bCOREcode/>
</Group>
</Group>
<Group>
<_2a>2 No</_2a>
<Q2b>2 Assured</Q2b>
<Q2ba/>
<_2bTenCode>TEN0021</_2bTenCode>
<_2cYears/>
</Group>
<Group>
<P1Age override-field="">37</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>1) Full Time</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field="">34</P2Age>
<P2AR/>
<P2Sex override-field="">Female</P2Sex>
<P2Rel>Other</P2Rel>
<P2Eco>1) Full Time</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>7 UC &#x2013; without housing element (not in receipt of HB and tenants not eligible for housing support e.g. residential care home)</Q6Ben>
</Group>
<Group>
<Q7Ben>3 None</Q7Ben>
<Q8Refused/>
<Q8Money override-field=""/>
<Q8a/>
</Group>
<Group>
<Q9a>8 (Non-violent) relationship breakdown with partner</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>1 Yes</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3/>
<Q10ib-4>Yes</Q10ib-4>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">28 Living with friends or family</Q11>
<Q12a>Blackpool</Q12a>
<Q12aONS>E09000009</Q12aONS>
<Q12b override-field="">FY1 1JD</Q12b>
<Q12bnot/>
<Q12c>1 Just moved to Local Authority area</Q12c>
<Q12d>1 Just moved to Local Authority area</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>2 No</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>1 Yes</Q15CBL>
<Q15CHR>2 No</Q15CHR>
<Q15CAP>2 No</Q15CAP>
</Group>
<Group>
<Q16>10 Other social landlord</Q16>
</Group>
</Group>
<Group>
<Q17>1 Weekly for 52 weeks</Q17>
<Q18ai override-field="">100.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field=""/>
<Q18av override-field="">100.00</Q18av>
<Q18d/>
<Q18dyes override-field=""/>
<Q19void>2021-04-15</Q19void>
<Q19repair/>
<Q20 override-field="">0</Q20>
<Q21a>PROPREF0042</Q21a>
</Group>
<Group>
<Q22 override-field=""/>
<Q23>1 Flat / maisonette</Q23>
<Q24>1 Purpose built</Q24>
<Q25>2 No</Q25>
<Q26>4 An Intermediate Rent basis</Q26>
<Q27>10 Relet - tenant evicted due to arrears</Q27>
</Group>
<Group>
<Q28Auth>Basingstoke &amp; Deane</Q28Auth>
<Q28ONS>E07000084</Q28ONS>
<Q28pc override-field="">RG21 3HU</Q28pc>
</Group>
<Group>
<F1Age>1</F1Age>
<F2Age>1</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>2</FAge>
<F1>1</F1>
<F2>1</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>2</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>0</P170>
<P270>0</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>0</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>1</P1FT>
<P2FT>1</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>2</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<Q1bV1>0</Q1bV1>
<Q1bV2>0</Q1bV2>
<Q1bV3>1</Q1bV3>
<Q1bVT>1</Q1bVT>
<P1Adult>1</P1Adult>
<P2Adult>1</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>2</PAdultT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>37</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>37</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>37</AgeDiff3>
<TODAY>2022-04-12Z</TODAY>
<FutureLimit>2022-04-27Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>C</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>1</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>1</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<TOTADULT>2</TOTADULT>
<NEW_OLD>2 Existing Tenant</NEW_OLD>
<Q18aValid>1</Q18aValid>
<Q18Valid>1</Q18Valid>
<VACDAYS>209</VACDAYS>
<HHMEMB>2</HHMEMB>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>1</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>2</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<HHTYPE>4 = 2 adults</HHTYPE>
<WEEKLYINC>200.00</WEEKLYINC>
<INCOME>200.00</INCOME>
<TYPEHB>13</TYPEHB>
<AFFRATE/>
<Weekinc>200.00</Weekinc>
<LETTYPE>1 Private Registered Provider</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000008</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>655</HCNUM>
<MANHCNUM>655</MANHCNUM>
<LAHA/>
<MANINGORGID>1</MANINGORGID>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13>13</HBTYPE13>
<HBTYPE14/>
<HBTYPE15/>
<HBTYPE>13</HBTYPE>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WRENT>100.00</WRENT>
<WTCHARGE>100.00</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG/>
<ChildBen>0.00</ChildBen>
<WTSHORTFALL1/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT1>100.00</WRENT1>
<WTCHARGE1>100.00</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1/>
<ChildBen1>0</ChildBen1>
</Group>
<Group>
<BSa>0</BSa>
<BSb>2</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>2</BEDROOMSTAND>
<BEDMINUSBEDS>0</BEDMINUSBEDS>
<WRENTreduced>100.00</WRENTreduced>
<NonDepDeduct>23.35</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>0</PrsnlAllowan>
<HousBenDisAl>0</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>23.35</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>10</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>15</VDAY>
<VMONTH>4</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>FY1</PPOSTC1>
<PPOSTC2>1JD</PPOSTC2>
<POSTCODE/>
<POSTCOD2/>
</Group>
</Group>

514
spec/fixtures/imports/logs/893ufj2s-lq77-42m4-rty6-ej09gh585uy1.xml vendored

@ -1,514 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-IR-GN" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-IR-GN</meta:form-name>
<meta:document-id>893ufj2s-lq77-42m4-rty6-ej09gh585uy1</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-04-11T13:46:23.953121Z</meta:created-date>
<meta:modified-date>2022-04-11T13:46:23.953121Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<IRProduct>2 London Living Rent</IRProduct>
<IRProductOther/>
<KeyDate>2021-11-10</KeyDate>
<FORM>300072</FORM>
<Landlord source-value="9">1 Private Registered Provider</Landlord>
<Group>
<_1btenagree>1 This Landlord</_1btenagree>
<_1bifanother/>
<_1bCOREcode/>
</Group>
</Group>
<Group>
<_2a>2 No</_2a>
<Q2b>2 Assured</Q2b>
<Q2ba/>
<_2bTenCode>TEN0021</_2bTenCode>
<_2cYears/>
</Group>
<Group>
<P1Age override-field="">37</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>1) Full Time</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field="">34</P2Age>
<P2AR/>
<P2Sex override-field="">Female</P2Sex>
<P2Rel>Other</P2Rel>
<P2Eco>1) Full Time</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>7 UC &#x2013; without housing element (not in receipt of HB and tenants not eligible for housing support e.g. residential care home)</Q6Ben>
</Group>
<Group>
<Q7Ben>3 None</Q7Ben>
<Q8Refused/>
<Q8Money override-field=""/>
<Q8a/>
</Group>
<Group>
<Q9a>8 (Non-violent) relationship breakdown with partner</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>1 Yes</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3/>
<Q10ib-4>Yes</Q10ib-4>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">28 Living with friends or family</Q11>
<Q12a>Blackpool</Q12a>
<Q12aONS>E09000009</Q12aONS>
<Q12b override-field="">FY1 1JD</Q12b>
<Q12bnot/>
<Q12c>1 Just moved to Local Authority area</Q12c>
<Q12d>1 Just moved to Local Authority area</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>2 No</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>2 No</Q15CBL>
<Q15CHR>2 No</Q15CHR>
<Q15CAP>2 No</Q15CAP>
</Group>
<Group>
<Q16>10 Other social landlord</Q16>
</Group>
</Group>
<Group>
<Q17>1 Weekly for 52 weeks</Q17>
<Q18ai override-field="">100.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field=""/>
<Q18av override-field="">100.00</Q18av>
<Q18d/>
<Q18dyes override-field=""/>
<Q19void>2021-04-15</Q19void>
<Q19repair/>
<Q20 override-field="">0</Q20>
<Q21a>PROPREF0042</Q21a>
</Group>
<Group>
<Q22 override-field=""/>
<Q23>1 Flat / maisonette</Q23>
<Q24>1 Purpose built</Q24>
<Q25>2 No</Q25>
<Q26>4 An Intermediate Rent basis</Q26>
<Q27>10 Relet - tenant evicted due to arrears</Q27>
</Group>
<Group>
<Q28Auth>Basingstoke &amp; Deane</Q28Auth>
<Q28ONS>E07000084</Q28ONS>
<Q28pc override-field="">RG21 3HU</Q28pc>
</Group>
<Group>
<F1Age>1</F1Age>
<F2Age>1</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>2</FAge>
<F1>1</F1>
<F2>1</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>2</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>0</P170>
<P270>0</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>0</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>1</P1FT>
<P2FT>1</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>2</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<Q1bV1>0</Q1bV1>
<Q1bV2>0</Q1bV2>
<Q1bV3>1</Q1bV3>
<Q1bVT>1</Q1bVT>
<P1Adult>1</P1Adult>
<P2Adult>1</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>2</PAdultT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>37</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>37</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>37</AgeDiff3>
<TODAY>2022-04-12Z</TODAY>
<FutureLimit>2022-04-27Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>C</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>1</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>1</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<TOTADULT>2</TOTADULT>
<NEW_OLD>2 Existing Tenant</NEW_OLD>
<Q18aValid>1</Q18aValid>
<Q18Valid>1</Q18Valid>
<VACDAYS>209</VACDAYS>
<HHMEMB>2</HHMEMB>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>1</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>2</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<HHTYPE>4 = 2 adults</HHTYPE>
<WEEKLYINC>200.00</WEEKLYINC>
<INCOME>200.00</INCOME>
<TYPEHB>13</TYPEHB>
<AFFRATE/>
<Weekinc>200.00</Weekinc>
<LETTYPE>1 Private Registered Provider</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000008</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>655</HCNUM>
<MANHCNUM>655</MANHCNUM>
<LAHA/>
<MANINGORGID>1</MANINGORGID>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13>13</HBTYPE13>
<HBTYPE14/>
<HBTYPE15/>
<HBTYPE>13</HBTYPE>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WRENT>100.00</WRENT>
<WTCHARGE>100.00</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG/>
<ChildBen>0.00</ChildBen>
<WTSHORTFALL1/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT1>100.00</WRENT1>
<WTCHARGE1>100.00</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1/>
<ChildBen1>0</ChildBen1>
</Group>
<Group>
<BSa>0</BSa>
<BSb>2</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>2</BEDROOMSTAND>
<BEDMINUSBEDS>0</BEDMINUSBEDS>
<WRENTreduced>100.00</WRENTreduced>
<NonDepDeduct>23.35</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>0</PrsnlAllowan>
<HousBenDisAl>0</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>23.35</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>10</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>15</VDAY>
<VMONTH>4</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>FY1</PPOSTC1>
<PPOSTC2>1JD</PPOSTC2>
<POSTCODE/>
<POSTCOD2/>
</Group>
</Group>

333
spec/fixtures/imports/logs/shared_ownership_sales_log.xml vendored

@ -1,333 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>shared_ownership_sales_log</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:48:28.255968Z</meta:created-date>
<meta:modified-date>2023-02-22T11:00:06.575832Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-17</CompletionDate>
<PurchaserCode>Shared ownership example</PurchaserCode>
<Ownership>1 Yes - a shared ownership scheme</Ownership>
<Q16SaleType>2 Shared Ownership</Q16SaleType>
<Q30SaleType/>
<Q38SaleType/>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">2</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age>30</P1Age>
<P1Sex override-field="">Male</P1Sex>
<P1Eco>1 Full Time - 30 hours or more a week</P1Eco>
<P1Eth>2 White: Irish</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>76000</CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>47000</IM1>
<IM2>0</IM2>
<IMT>235000</IMT>
<MortMultiple>0</MortMultiple>
<Form>300204</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>1</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>1</Q23CHK>
<Q16typeCHK>2</Q16typeCHK>
<Q16Q23>3</Q16Q23>
<DAY>17</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY>6</HODAY>
<HOMONTH>9</HOMONTH>
<HOYEAR>2022</HOYEAR>
<EXDAY>8</EXDAY>
<EXMONTH>1</EXMONTH>
<EXYEAR>2023</EXYEAR>
<PPOSTC1>SW14</PPOSTC1>
<PPOSTC2>7QP</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>2 Private registered provider (PRP) or housing association tenant</Q6PrevTenure>
<Q7Postcode override-field="">SW14 7QP</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Richmond-upon-Thames</Q7PrevLocation>
<Q7ONSLACode>E09000027</Q7ONSLACode>
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>8 Don&#x2019;t know</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>1 Yes</P1IncKnown>
<Q2Person1Income>47000</Q2Person1Income>
<Q2Person1Mortgage>1 Yes</Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown>1 Yes</savingsKnown>
<Q3Savings override-field="true">89000</Q3Savings>
<Q4PrevOwnedProperty>1 Yes</Q4PrevOwnedProperty>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase>2 No</Q17aStaircase>
<PercentBought override-field=""/>
<PercentOwns>30</PercentOwns>
<Q17Resale>2 No</Q17Resale>
<Q18ContractExchange override-field="">2023-01-08</Q18ContractExchange>
<Q18PracticalCompletion override-field="">2022-09-06</Q18PracticalCompletion>
<Q19Rehoused>2 No</Q19Rehoused>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field="true">550000</Q22PurchasePrice>
<Q23Equity override-field="">30</Q23Equity>
<MortgageUsedSO>1 Yes</MortgageUsedSO>
<Q24Mortgage override-field="">76000</Q24Mortgage>
<Q24aMortgageLender>Nationwide</Q24aMortgageLender>
<Q24b>33</Q24b>
<Q25Borrowing>2 No</Q25Borrowing>
<Q26CashDeposit override-field="">89000</Q26CashDeposit>
<Q27SocialHomeBuy/>
<Q28MonthlyRent>912.00</Q28MonthlyRent>
<Q29MonthlyCharges>134.24</Q29MonthlyCharges>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>3 = 1 adult</HHTYPE>
</Group>
<Group>
<DerSaleType>2 Shared Ownership</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>1</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

9
spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml vendored

@ -1,9 +0,0 @@
<mgmtgroup:mgmtgroup xmlns:mgmtgroup="dclg:mgmtgroup">
<mgmtgroup:id>6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d</mgmtgroup:id>
<mgmtgroup:name id-field="Y">Management Group</mgmtgroup:name>
<mgmtgroup:arrangement_type>O</mgmtgroup:arrangement_type>
<mgmtgroup:agent>456</mgmtgroup:agent>
<mgmtgroup:institution>7c5bd5fb549c09z2c55d9cb90d7ba84927e64618</mgmtgroup:institution>
<mgmtgroup:status>Approved</mgmtgroup:status>
<mgmtgroup:visible-id>0123</mgmtgroup:visible-id>
</mgmtgroup:mgmtgroup>

5
spec/fixtures/imports/rent-period/ebd22326d33e389e9f1bfd546979d2c05f9e68d6.xml vendored

@ -1,5 +0,0 @@
<rent-period:rent-period xmlns:rent-period="dclg:rent-period">
<rent-period:id>ebd22326d33e389e9f1bfd546979d2c05f9e68d6</rent-period:id>
<rent-period:institution>44026acc7ed5c29516b26f2a5deb639e5e37966d</rent-period:institution>
<rent-period:period>1</rent-period:period>
</rent-period:rent-period>

350
spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml vendored

@ -1,350 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>discounted_ownership_sales_log</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:54:51.786722Z</meta:created-date>
<meta:modified-date>2023-02-22T10:59:45.88188Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<Qdp/>
<CompletionDate>2023-02-01</CompletionDate>
<PurchaserCode>Discount ownership example</PurchaserCode>
<Ownership>2 Yes - a discount ownership scheme</Ownership>
<Q16SaleType/>
<Q30SaleType>14 Preserved Right to Buy (PRTB)</Q30SaleType>
<Q38SaleType/>
<Q38OtherSale/>
<company/>
<LiveInBuyer/>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>1 No</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">3</Q11Bedrooms>
<Q12PropertyType>3 House</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<Q14Postcode override-field="">GL519EX</Q14Postcode>
<!-- replace with commented options to test in the future -->
<!-- <Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode> -->
<Q14PropertyLocation>Cheltenham</Q14PropertyLocation>
<Q14ONSLACode>E07000078</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age/>
<P1Sex override-field=""/>
<P1Eco/>
<P1Eth/>
<P1Nat/>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>134750</CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>0</IM1>
<IM2>0</IM2>
<IMT>0</IMT>
<MortMultiple>1</MortMultiple>
<Form>300203</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>0</Q16CHK>
<Q30CHK>1</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>0</Q23CHK>
<Q16typeCHK>0</Q16typeCHK>
<Q16Q23>0</Q16Q23>
<DAY>1</DAY>
<MONTH>2</MONTH>
<YEAR>2023</YEAR>
<HODAY/>
<HOMONTH/>
<HOYEAR/>
<EXDAY/>
<EXMONTH/>
<EXYEAR/>
<PPOSTC1>GL51</PPOSTC1>
<PPOSTC2>9EX</PPOSTC2>
<!-- replace with commented options to test in the future -->
<!-- <PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2> -->
<PCODE1>GL51</PCODE1>
<PCODE2>9EX</PCODE2>
<NOINT>1</NOINT>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q6PrevTenure/> -->
<Q6PrevTenure>3 Private tenant</Q6PrevTenure>
<Q7Postcode override-field="">GL519EX</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Cheltenham</Q7PrevLocation>
<Q7ONSLACode>E07000078</Q7ONSLACode>
<!-- replace with commented options to test in the future -->
<!-- <PREGYRHA/> -->
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF/>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability/>
<Q10Wheelchair override-field=""/>
</Group>
<Group>
<P1IncKnown/>
<Q2Person1Income/>
<Q2Person1Mortgage>1 Yes</Q2Person1Mortgage>
<!-- replace with commented options to test in the future -->
<!-- <Q2Person1Mortgage/> -->
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a/>
<savingsKnown/>
<Q3Savings override-field=""/>
<Q4PrevOwnedProperty/>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase/>
<PercentBought override-field=""/>
<PercentOwns/>
<Q17Resale/>
<Q18ContractExchange override-field=""/>
<Q18PracticalCompletion override-field=""/>
<Q19Rehoused/>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field=""/>
<Q23Equity override-field=""/>
<MortgageUsedSO/>
<Q24Mortgage override-field=""/>
<Q24aMortgageLender/>
<Q24b/>
<Q25Borrowing/>
<Q26CashDeposit override-field=""/>
<Q27SocialHomeBuy/>
<Q28MonthlyRent/>
<Q29MonthlyCharges/>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field="">275000</Q31PurchasePrice>
<Q32Reductions override-field=""/>
<Q33Discount override-field="">51</Q33Discount>
<MortgageUsedDO>1 Yes</MortgageUsedDO>
<Q34Mortgage override-field="true">134750</Q34Mortgage>
<Q34a>Halifax</Q34a>
<!-- replace with commented options to test in the future -->
<!-- <Q34b/> -->
<Q34b>33</Q34b>
<Q35Borrowing>2 No</Q35Borrowing>
<Q36CashDeposit>0</Q36CashDeposit>
<Q37MonthlyCharges>10.00</Q37MonthlyCharges>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>0</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>9 = other</HHTYPE>
<!-- replace with commented options to test in the future -->
<!-- <HHTYPE>3 = 1 adult</HHTYPE> -->
</Group>
<Group>
<DerSaleType>14 Preserved Right to Buy (PRTB)</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>0</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>0</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

524
spec/fixtures/imports/sales_logs/lettings_log.xml vendored

@ -1,524 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2021-CORE-SR-SH" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2021-CORE-SR-SH</meta:form-name>
<meta:document-id>lettings_log</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2022-01-05T12:50:20.39153Z</meta:created-date>
<meta:modified-date>2022-01-05T12:50:20.39153Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2021</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<KeyDate>2021-11-05</KeyDate>
<FORM>123456</FORM>
<Landlord source-value="2">2 Local Authority</Landlord>
<Group>
<_1cmangroupcode>0123</_1cmangroupcode>
<_1cschemecode>10</_1cschemecode>
<schPC/>
<Q1e>3 No</Q1e>
</Group>
</Group>
<Group>
<_2a>2 No</_2a>
<Q2b>1 Secure (inc flexible)</Q2b>
<Q2ba/>
<_2bTenCode>14044912001</_2bTenCode>
<_2cYears>2</_2cYears>
</Group>
<Group>
<P1Age override-field="">72</P1Age>
<P1AR/>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>5) Retired</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>1 UK national resident in UK</P1Nat>
<P2Age override-field="">74</P2Age>
<P2AR/>
<P2Sex override-field="">Male</P2Sex>
<P2Rel>Partner</P2Rel>
<P2Eco>5) Retired</P2Eco>
<P3Age override-field=""/>
<P3AR/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age override-field=""/>
<P4AR/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age override-field=""/>
<P5AR/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age override-field=""/>
<P6AR/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age override-field=""/>
<P7AR/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age override-field=""/>
<P8AR/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<Group>
<ArmedF>2 No</ArmedF>
<LeftAF/>
<Inj/>
<Preg override-field="">2 No</Preg>
</Group>
<Group>
<Q6Ben>9 Not in receipt of either UC or HB</Q6Ben>
</Group>
<Group>
<Q7Ben>2 Some</Q7Ben>
<Q8Refused>Refused</Q8Refused>
<Q8Money override-field=""/>
<Q8a/>
</Group>
<Group>
<Q9a>13 Property unsuitable because of ill health / disability</Q9a>
<Q9aa/>
</Group>
<Group>
<_9b override-field="">2 No</_9b>
<Q10-a/>
<Q10-b/>
<Q10-c/>
<Q10-f/>
<Q10-g>Yes</Q10-g>
<Q10-h/>
<Q10ia>1 Yes</Q10ia>
<Q10ib-1/>
<Q10ib-2/>
<Q10ib-3>Yes</Q10ib-3>
<Q10ib-4/>
<Q10ib-5/>
<Q10ib-6/>
<Q10ib-7/>
<Q10ib-8/>
<Q10ib-9/>
<Q10ib-10/>
<Q11 override-field="">26 Owner occupation (private)</Q11>
<Q12a>DLUHC</Q12a>
<Q12aONS>E08000035</Q12aONS>
<Q12b override-field="">S80 4DJ</Q12b>
<Q12bnot/>
<Q12c>5 5 years or more</Q12c>
<Q12d>9 3 years but under 4 years</Q12d>
</Group>
<Group>
<Q13>1 Not homeless</Q13>
<Q14a>2 No</Q14a>
<Q14b1/>
<Q14b2/>
<Q14b3/>
<Q14b4/>
<Q14b5/>
</Group>
<Group>
<Q15CBL>1 Yes</Q15CBL>
<Q15CHR>1 Yes</Q15CHR>
<Q15CAP>1 Yes</Q15CAP>
</Group>
<Group>
<Q16>2 Tenant applied direct (no referral or nomination)</Q16>
</Group>
</Group>
<Group>
<Q17>7 Weekly for 48 weeks</Q17>
<Q18ai override-field="true">125.00</Q18ai>
<Q18aii override-field=""/>
<Q18aiii override-field=""/>
<Q18aiv override-field="">7.00</Q18aiv>
<Q18av override-field="">132.00</Q18av>
<Q18b override-field=""/>
<Q18c/>
<Q18d/>
<Q18dyes override-field=""/>
<Q19void>2021-08-24</Q19void>
<Q19repair/>
<Q19supsch/>
<Q20 override-field="">0</Q20>
<Q21a>14044912</Q21a>
</Group>
<Group>
<Q25>1 Yes</Q25>
<Q27>15 First let of newbuild property</Q27>
</Group>
<Group>
<F1Age>0</F1Age>
<F2Age>0</F2Age>
<F3Age>0</F3Age>
<F4Age>0</F4Age>
<F5Age>0</F5Age>
<F6Age>0</F6Age>
<F7Age>0</F7Age>
<F8Age>0</F8Age>
<FAge>0</FAge>
<F1>1</F1>
<F2>0</F2>
<F3>0</F3>
<F4>0</F4>
<F5>0</F5>
<F6>0</F6>
<F7>0</F7>
<F8>0</F8>
<F>1</F>
<P1100>0</P1100>
<P2100>0</P2100>
<P3100>0</P3100>
<P4100>0</P4100>
<P5100>0</P5100>
<P6100>0</P6100>
<P7100>0</P7100>
<P8100>0</P8100>
<_100>0</_100>
<P170>1</P170>
<P270>1</P270>
<P370>0</P370>
<P470>0</P470>
<P570>0</P570>
<P670>0</P670>
<P770>0</P770>
<P870>0</P870>
<_70>1</_70>
<P1PT>0</P1PT>
<P2PT>0</P2PT>
<P3PT>0</P3PT>
<P4PT>0</P4PT>
<P5PT>0</P5PT>
<P6PT>0</P6PT>
<P7PT>0</P7PT>
<P8PT>0</P8PT>
<PT>0</PT>
<P1FT>0</P1FT>
<P2FT>0</P2FT>
<P3FT>0</P3FT>
<P4FT>0</P4FT>
<P5FT>0</P5FT>
<P6FT>0</P6FT>
<P7FT>0</P7FT>
<P8FT>0</P8FT>
<FT>0</FT>
<P1Stud>0</P1Stud>
<P2Stud>0</P2Stud>
<P3Stud>0</P3Stud>
<P4Stud>0</P4Stud>
<P5Stud>0</P5Stud>
<P6Stud>0</P6Stud>
<P7Stud>0</P7Stud>
<P8Stud>0</P8Stud>
<Stud>0</Stud>
<P2Child>0</P2Child>
<P3Child>0</P3Child>
<P4Child>0</P4Child>
<P5Child>0</P5Child>
<P6Child>0</P6Child>
<P7Child>0</P7Child>
<P8Child>0</P8Child>
<Child>0</Child>
<P2Partner>1</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>1</Partner>
<Q1cV1>1</Q1cV1>
<Q1cV2>1</Q1cV2>
<Q1cVT>2</Q1cVT>
<P1Adult>1</P1Adult>
<P2Adult>1</P2Adult>
<P3Adult>0</P3Adult>
<P4Adult>0</P4Adult>
<P5Adult>0</P5Adult>
<P6Adult>0</P6Adult>
<P7Adult>0</P7Adult>
<P8Adult>0</P8Adult>
<PAdultT>2</PAdultT>
<P2PAge>74</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE>74</PAGE>
<P2ChildAge>0</P2ChildAge>
<P3ChildAge>0</P3ChildAge>
<P4ChildAge>0</P4ChildAge>
<P5ChildAge>0</P5ChildAge>
<P6ChildAge>0</P6ChildAge>
<P7ChildAge>0</P7ChildAge>
<P8ChildAge>0</P8ChildAge>
<ChildAgeMin>0</ChildAgeMin>
<AgeDiff1>72</AgeDiff1>
<AgeDiff2>0</AgeDiff2>
<AgeDiff3>74</AgeDiff3>
<TODAY>2022-01-05Z</TODAY>
<FutureLimit>2022-01-20Z</FutureLimit>
<minmax1/>
<minmax2/>
<minmax3/>
<minmax4/>
<minmax5/>
<minmax6/>
<minmax7/>
<minmax8/>
<minmax9/>
<minmax0/>
<minmax10/>
<minmaxT/>
<Q10av>0</Q10av>
<Q10bv>0</Q10bv>
<Q10cv>0</Q10cv>
<Q10fv>0</Q10fv>
<Q10gv>20</Q10gv>
<Q10hv>0</Q10hv>
<Q10Validate>20</Q10Validate>
<Q2bv>A</Q2bv>
<P2Agev>1</P2Agev>
<P2Sexv>1</P2Sexv>
<P2Relv>1</P2Relv>
<P2Ecov>1</P2Ecov>
<P2valid>4</P2valid>
<P3Agev>0</P3Agev>
<P3Sexv>0</P3Sexv>
<P3Relv>0</P3Relv>
<P3Ecov>0</P3Ecov>
<P3valid>0</P3valid>
<P4Agev>0</P4Agev>
<P4Sexv>0</P4Sexv>
<P4Relv>0</P4Relv>
<P4Ecov>0</P4Ecov>
<P4valid>0</P4valid>
<P5Agev>0</P5Agev>
<P5Sexv>0</P5Sexv>
<P5Relv>0</P5Relv>
<P5Ecov>0</P5Ecov>
<P5valid>0</P5valid>
<P6Agev>0</P6Agev>
<P6Sexv>0</P6Sexv>
<P6Relv>0</P6Relv>
<P6Ecov>0</P6Ecov>
<P6valid>0</P6valid>
<P7Agev>0</P7Agev>
<P7Sexv>0</P7Sexv>
<P7Relv>0</P7Relv>
<P7Ecov>0</P7Ecov>
<P7valid>0</P7valid>
<P8Agev>0</P8Agev>
<P8Sexv>0</P8Sexv>
<P8Relv>0</P8Relv>
<P8Ecov>0</P8Ecov>
<P8valid>0</P8valid>
<Q14b1v>0</Q14b1v>
<Q14b2v>0</Q14b2v>
<Q14b3v>0</Q14b3v>
<Q14b4v>0</Q14b4v>
<Q14b5v>0</Q14b5v>
<Q14bv>0</Q14bv>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2ARefused>0</P2ARefused>
<P3ARefused>0</P3ARefused>
<P4ARefused>0</P4ARefused>
<P5ARefused>0</P5ARefused>
<P6ARefused>0</P6ARefused>
<P7ARefused>0</P7ARefused>
<P8ARefused>0</P8ARefused>
<TAREUSED>0</TAREUSED>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<TOTREFUSED>0</TOTREFUSED>
</Group>
<Group>
<ChildBen>0.00</ChildBen>
<TOTADULT>2</TOTADULT>
<NEW_OLD>1 New Tenant</NEW_OLD>
<WCHCHRG/>
<VACDAYS>73</VACDAYS>
<HHMEMB>2</HHMEMB>
<HHTYPEP1A>0</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>0</TADULT>
<HHTYPEP1E>1</HHTYPEP1E>
<HHTYPEP2E>1</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>2</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q18aValid>1</Q18aValid>
<Q18bValid>0</Q18bValid>
<Q18cValid>0</Q18cValid>
<Q18Valid>1</Q18Valid>
<HHTYPE>2 = 2 Adults at least one is an Elder</HHTYPE>
<WEEKLYINC/>
<INCOME/>
<TYPEHB>15.00</TYPEHB>
<AFFRATE/>
<Weekinc/>
<LETTYPE>2 Local Authority</LETTYPE>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000004</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>DLUHC</OWNINGORGNAME>
<MANINGORGNAME>DLUHC</MANINGORGNAME>
<HCNUM>N/A</HCNUM>
<MANHCNUM>N/A</MANHCNUM>
<LAHA/>
<MANINGORGID>2</MANINGORGID>
<Q28same1>false</Q28same1>
<HBTYPE1/>
<HBTYPE2/>
<HBTYPE3/>
<HBTYPE4/>
<HBTYPE5/>
<HBTYPE6/>
<HBTYPE7/>
<HBTYPE8/>
<HBTYPE9/>
<HBTYPE10/>
<HBTYPE11/>
<HBTYPE12/>
<HBTYPE13/>
<HBTYPE14/>
<HBTYPE15>15</HBTYPE15>
<HBTYPE>15</HBTYPE>
<SCHEME>000001005048</SCHEME>
<MANTYPE>D</MANTYPE>
<UNITS>15</UNITS>
<UNITTYPE>6</UNITTYPE>
<SCHTYPE>7</SCHTYPE>
<REGHOME>1</REGHOME>
<SUPPORT>2</SUPPORT>
<MOBSTAND>A</MOBSTAND>
<INTSTAY>P</INTSTAY>
<CLIGRP1>M</CLIGRP1>
<CLIGRP2/>
<Q28Auth>DLUHC</Q28Auth>
<Q28ONS>E08000035</Q28ONS>
<Q28pc override-field="">S80 4QE</Q28pc>
<Q28same/>
<P1R>0</P1R>
<P2R>0</P2R>
<P3R>0</P3R>
<P4R>0</P4R>
<P5R>0</P5R>
<P6R>0</P6R>
<P7R>0</P7R>
<P8R>0</P8R>
<REFUSEDTOT>0</REFUSEDTOT>
<REFUSED/>
<WTSHORTFALL/>
<WTSHORTFALLHB/>
<WTSHORTFALLHE/>
<WRENT>115.38</WRENT>
<WTCHARGE>121.85</WTCHARGE>
<WSCHARGE/>
<WPSCHRGE/>
<WSUPCHRG>6.46</WSUPCHRG>
<WTSHORTFALL1/>
<WRENT1>115.38</WRENT1>
<WTCHARGE1>121.85</WTCHARGE1>
<WSCHARGE1/>
<WPSCHRGE1/>
<WSUPCHRG1>6.46</WSUPCHRG1>
</Group>
<Group>
<BSa>1</BSa>
<BSb>0</BSb>
<BSc>0</BSc>
<BScm>0</BScm>
<BScf>0</BScf>
<BSd>0</BSd>
<BSdm>0</BSdm>
<BSdf>0</BSdf>
<BSe>0</BSe>
<BSem>0</BSem>
<BSef>0</BSef>
<BSf>0</BSf>
<BSfm>0</BSfm>
<BSff>0</BSff>
<BSfmx>0</BSfmx>
<BSffx>0</BSffx>
<BEDROOMSTAND>1</BEDROOMSTAND>
<BEDMINUSBEDS/>
<WRENTreduced>115.38</WRENTreduced>
<NonDepDeduct>0</NonDepDeduct>
<RENTHB/>
<ChildAllowan>0</ChildAllowan>
<PrsnlAllowan>117.4</PrsnlAllowan>
<HousBenDisAl>10</HousBenDisAl>
<PAIDHB/>
<HCNETAF/>
<ChldAlloCat1>0</ChldAlloCat1>
<ChldAlloCat2>0</ChldAlloCat2>
<P2NnDepDedct>0</P2NnDepDedct>
<P3NnDepDedct>0</P3NnDepDedct>
<P4NnDepDedct>0</P4NnDepDedct>
<P5NnDepDedct>0</P5NnDepDedct>
<P6NnDepDedct>0</P6NnDepDedct>
<P7NnDepDedct>0</P7NnDepDedct>
<P8NnDepDedct>0</P8NnDepDedct>
<DAY>5</DAY>
<MONTH>11</MONTH>
<YEAR>2021</YEAR>
<VDAY>24</VDAY>
<VMONTH>8</VMONTH>
<VYEAR>2021</VYEAR>
<MRCDAY/>
<MRCMONTH/>
<MRCYEAR/>
<PPOSTC1>LS16</PPOSTC1>
<PPOSTC2>6FT</PPOSTC2>
<POSTCODE>LS16</POSTCODE>
<POSTCOD2>6FT</POSTCOD2>
</Group>
</Group>

339
spec/fixtures/imports/sales_logs/outright_sale_sales_log.xml vendored

@ -1,339 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>outright_sale_sales_log</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T12:09:45.809134Z</meta:created-date>
<meta:modified-date>2023-02-22T10:59:01.709949Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-16</CompletionDate>
<PurchaserCode>Outright ownership example</PurchaserCode>
<Ownership>3 No - this is an outright or other sale</Ownership>
<Q16SaleType/>
<Q30SaleType/>
<Q38SaleType>10 Outright</Q38SaleType>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">1</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<UPRN/>
<AddressLine1/>
<AddressLine2/>
<TownCity/>
<County/>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>2 No</Q15Wheelchair>
</Group>
<Group>
<P1Age>75</P1Age>
<P1Sex override-field="">Female</P1Sex>
<P1Eco>5 Retired</P1Eco>
<P1Eth>1 White: English/Scottish/Welsh/Northern Irish/British</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>0</CALCMORT>
<MORTGAGEUSED>2</MORTGAGEUSED>
<IM1>0</IM1>
<IM2>0</IM2>
<IMT>0</IMT>
<MortMultiple>0</MortMultiple>
<Form>300202</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15>B</minmaxP15>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T>B</minmaxP1T>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>0</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>1</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>0</Q23CHK>
<Q16typeCHK>0</Q16typeCHK>
<Q16Q23>0</Q16Q23>
<DAY>16</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY/>
<HOMONTH/>
<HOYEAR/>
<EXDAY/>
<EXMONTH/>
<EXYEAR/>
<PPOSTC1>B95</PPOSTC1>
<PPOSTC2>5HZ</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>3 Private tenant</Q6PrevTenure>
<Q7Postcode override-field="">B95 5HZ</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Stratford-on-Avon</Q7PrevLocation>
<Q7ONSLACode>E07000221</Q7ONSLACode>
<PREGYRHA/>
<PREGORHA/>
<PREGLA>Yes</PREGLA>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>7 No</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>2 No</P1IncKnown>
<Q2Person1Income/>
<!-- replace with commented options to test in the future -->
<!-- <Q2Person1Mortgage/> -->
<Q2Person1Mortgage>2 No</Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown/>
<Q3Savings override-field=""/>
<Q4PrevOwnedProperty>2 No</Q4PrevOwnedProperty>
</Group>
<Group>
<Q16aProplen2/>
<Q17aStaircase/>
<PercentBought override-field=""/>
<PercentOwns/>
<Q17Resale/>
<Q18ContractExchange override-field=""/>
<Q18PracticalCompletion override-field=""/>
<Q19Rehoused/>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field=""/>
<Q23Equity override-field=""/>
<MortgageUsedSO/>
<Q24Mortgage override-field=""/>
<Q24aMortgageLender/>
<Q24b/>
<Q25Borrowing/>
<Q26CashDeposit override-field=""/>
<Q27SocialHomeBuy/>
<Q28MonthlyRent/>
<Q29MonthlyCharges/>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field="">300000</Q40PurchasePrice>
<MortgageUsedOS>2 No</MortgageUsedOS>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field="">300000</Q43CashDeposit>
<Q44MonthlyCharges/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>1 = 1 elder</HHTYPE>
</Group>
<Group>
<DerSaleType>10 Outright</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>0</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>0</TADULT>
<HHTYPEP1E>1</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>1</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>0</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>1</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

342
spec/fixtures/imports/sales_logs/shared_ownership_sales_log.xml vendored

@ -1,342 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>shared_ownership_sales_log</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:48:28.255968Z</meta:created-date>
<meta:modified-date>2023-02-22T11:00:06.575832Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-17</CompletionDate>
<PurchaserCode>Shared ownership example</PurchaserCode>
<Ownership>1 Yes - a shared ownership scheme</Ownership>
<Q16SaleType>2 Shared Ownership</Q16SaleType>
<Q30SaleType/>
<Q38SaleType/>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<BUY2LIVEIN/>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">2</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<UPRN/>
<AddressLine1/>
<AddressLine2/>
<TownCity/>
<County/>
<PREVSHARED/>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age>30</P1Age>
<P1Sex override-field="">Male</P1Sex>
<P1Eco>1 Full Time - 30 hours or more a week</P1Eco>
<P1Eth>2 White: Irish</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P2Eth/>
<P2Nat/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>76000</CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>47000</IM1>
<IM2>0</IM2>
<IMT>235000</IMT>
<MortMultiple>0</MortMultiple>
<Form>300204</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>1</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>1</Q23CHK>
<Q16typeCHK>2</Q16typeCHK>
<Q16Q23>3</Q16Q23>
<DAY>17</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY>6</HODAY>
<HOMONTH>9</HOMONTH>
<HOYEAR>2022</HOYEAR>
<EXDAY>8</EXDAY>
<EXMONTH>1</EXMONTH>
<EXYEAR>2023</EXYEAR>
<PPOSTC1>SW14</PPOSTC1>
<PPOSTC2>7QP</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>2 Private registered provider (PRP) or housing association tenant</Q6PrevTenure>
<Q7Postcode override-field="">SW14 7QP</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Richmond-upon-Thames</Q7PrevLocation>
<Q7ONSLACode>E09000027</Q7ONSLACode>
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>8 Don&#x2019;t know</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>1 Yes</P1IncKnown>
<Q2Person1Income>47000</Q2Person1Income>
<Q2Person1Mortgage>1 Yes</Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown>1 Yes</savingsKnown>
<Q3Savings override-field="true">89000</Q3Savings>
<Q4PrevOwnedProperty>1 Yes</Q4PrevOwnedProperty>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase>2 No</Q17aStaircase>
<PercentBought override-field=""/>
<PercentOwns>30</PercentOwns>
<Q17Resale>2 No</Q17Resale>
<Q18ContractExchange override-field="">2023-01-08</Q18ContractExchange>
<Q18PracticalCompletion override-field="">2022-09-06</Q18PracticalCompletion>
<Q19Rehoused>2 No</Q19Rehoused>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field="true">550000</Q22PurchasePrice>
<Q23Equity override-field="">30</Q23Equity>
<MortgageUsedSO>1 Yes</MortgageUsedSO>
<Q24Mortgage override-field="">76000</Q24Mortgage>
<Q24aMortgageLender>Nationwide</Q24aMortgageLender>
<Q24b>33</Q24b>
<Q25Borrowing>2 No</Q25Borrowing>
<Q26CashDeposit override-field="">89000</Q26CashDeposit>
<Q27SocialHomeBuy/>
<Q28MonthlyRent>912.00</Q28MonthlyRent>
<Q29MonthlyCharges>134.24</Q29MonthlyCharges>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>3 = 1 adult</HHTYPE>
</Group>
<Group>
<DerSaleType>2 Shared Ownership</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>1</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

334
spec/fixtures/imports/sales_logs/shared_ownership_sales_log2.xml vendored

@ -1,334 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>shared_ownership_sales_log2</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:48:28.255968Z</meta:created-date>
<meta:modified-date>2023-02-22T11:00:06.575832Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Bulk Upload</meta:upload-method>
<meta:upload-id>8dda8f1a-f5a1-4827-8d82-dd7fd9258eab</meta:upload-id>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-17</CompletionDate>
<PurchaserCode>Shared ownership example 2</PurchaserCode>
<Ownership>1 Yes - a shared ownership scheme</Ownership>
<Q16SaleType>2 Shared Ownership</Q16SaleType>
<Q30SaleType/>
<Q38SaleType/>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">2</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age>30</P1Age>
<P1Sex override-field="">Male</P1Sex>
<P1Eco>1 Full Time - 30 hours or more a week</P1Eco>
<P1Eth>2 White: Irish</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>76000</CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>47000</IM1>
<IM2>0</IM2>
<IMT>235000</IMT>
<MortMultiple>0</MortMultiple>
<Form>300204</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>1</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>1</Q23CHK>
<Q16typeCHK>2</Q16typeCHK>
<Q16Q23>3</Q16Q23>
<DAY>17</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY>6</HODAY>
<HOMONTH>9</HOMONTH>
<HOYEAR>2022</HOYEAR>
<EXDAY>8</EXDAY>
<EXMONTH>1</EXMONTH>
<EXYEAR>2023</EXYEAR>
<PPOSTC1>SW14</PPOSTC1>
<PPOSTC2>7QP</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>2 Private registered provider (PRP) or housing association tenant</Q6PrevTenure>
<Q7Postcode override-field="">SW14 7QP</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Richmond-upon-Thames</Q7PrevLocation>
<Q7ONSLACode>E09000027</Q7ONSLACode>
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>8 Don&#x2019;t know</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>1 Yes</P1IncKnown>
<Q2Person1Income>47000</Q2Person1Income>
<Q2Person1Mortgage>1 Yes</Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown>1 Yes</savingsKnown>
<Q3Savings override-field="true">89000</Q3Savings>
<Q4PrevOwnedProperty>1 Yes</Q4PrevOwnedProperty>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase>2 No</Q17aStaircase>
<PercentBought override-field=""/>
<PercentOwns>30</PercentOwns>
<Q17Resale>2 No</Q17Resale>
<Q18ContractExchange override-field="">2023-01-08</Q18ContractExchange>
<Q18PracticalCompletion override-field="">2022-09-06</Q18PracticalCompletion>
<Q19Rehoused>2 No</Q19Rehoused>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field="true">550000</Q22PurchasePrice>
<Q23Equity override-field="">30</Q23Equity>
<MortgageUsedSO>1 Yes</MortgageUsedSO>
<Q24Mortgage override-field="">76000</Q24Mortgage>
<Q24aMortgageLender>Nationwide</Q24aMortgageLender>
<Q24b>33</Q24b>
<Q25Borrowing>2 No</Q25Borrowing>
<Q26CashDeposit override-field="">89000</Q26CashDeposit>
<Q27SocialHomeBuy/>
<Q28MonthlyRent>912.00</Q28MonthlyRent>
<Q29MonthlyCharges>134.24</Q29MonthlyCharges>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>3 = 1 adult</HHTYPE>
</Group>
<Group>
<DerSaleType>2 Shared Ownership</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>1</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

333
spec/fixtures/imports/sales_logs/shared_ownership_sales_log3.xml vendored

@ -1,333 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>shared_ownership_sales_log3</meta:document-id>
<meta:owner-user-id>c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:48:28.255968Z</meta:created-date>
<meta:modified-date>2023-02-22T11:00:06.575832Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-17</CompletionDate>
<PurchaserCode>Shared ownership example</PurchaserCode>
<Ownership>1 Yes - a shared ownership scheme</Ownership>
<Q16SaleType>2 Shared Ownership</Q16SaleType>
<Q30SaleType/>
<Q38SaleType/>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">2</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age>30</P1Age>
<P1Sex override-field="">Male</P1Sex>
<P1Eco>1 Full Time - 30 hours or more a week</P1Eco>
<P1Eth>2 White: Irish</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT></CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>47000</IM1>
<IM2>0</IM2>
<IMT>235000</IMT>
<MortMultiple>0</MortMultiple>
<Form>300204</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>1</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>1</Q23CHK>
<Q16typeCHK>2</Q16typeCHK>
<Q16Q23>3</Q16Q23>
<DAY>17</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY>6</HODAY>
<HOMONTH>9</HOMONTH>
<HOYEAR>2022</HOYEAR>
<EXDAY>8</EXDAY>
<EXMONTH>1</EXMONTH>
<EXYEAR>2023</EXYEAR>
<PPOSTC1>SW14</PPOSTC1>
<PPOSTC2>7QP</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>2 Private registered provider (PRP) or housing association tenant</Q6PrevTenure>
<Q7Postcode override-field="">SW14 7QP</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Richmond-upon-Thames</Q7PrevLocation>
<Q7ONSLACode>E09000027</Q7ONSLACode>
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>8 Don&#x2019;t know</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>1 Yes</P1IncKnown>
<Q2Person1Income>47000</Q2Person1Income>
<Q2Person1Mortgage></Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown>1 Yes</savingsKnown>
<Q3Savings override-field="true">89000</Q3Savings>
<Q4PrevOwnedProperty>1 Yes</Q4PrevOwnedProperty>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase>2 No</Q17aStaircase>
<PercentBought override-field=""/>
<PercentOwns>30</PercentOwns>
<Q17Resale>2 No</Q17Resale>
<Q18ContractExchange override-field="">2023-01-08</Q18ContractExchange>
<Q18PracticalCompletion override-field="">2022-09-06</Q18PracticalCompletion>
<Q19Rehoused>2 No</Q19Rehoused>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field="true">550000</Q22PurchasePrice>
<Q23Equity override-field="">30</Q23Equity>
<MortgageUsedSO>1 Yes</MortgageUsedSO>
<Q24Mortgage override-field="">76000</Q24Mortgage>
<Q24aMortgageLender>Nationwide</Q24aMortgageLender>
<Q24b>33</Q24b>
<Q25Borrowing>2 No</Q25Borrowing>
<Q26CashDeposit override-field="">89000</Q26CashDeposit>
<Q27SocialHomeBuy/>
<Q28MonthlyRent>912.00</Q28MonthlyRent>
<Q29MonthlyCharges>134.24</Q29MonthlyCharges>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>3 = 1 adult</HHTYPE>
</Group>
<Group>
<DerSaleType>2 Shared Ownership</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>1</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

333
spec/fixtures/imports/sales_logs/shared_ownership_sales_log4.xml vendored

@ -1,333 +0,0 @@
<Group xmlns="http://data.gov.uk/core/logs/2022-CORE-Sales" xmlns:app="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:meta="http://data.gov.uk/core/metadata" xmlns:svc="http://www.w3.org/2007/app" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xfimpl="http://www.w3.org/2002/xforms/implementation" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<meta:metadata xmlns:es="http://www.ecmascript.org/" xmlns:xqx="http://www.w3.org/2005/XQueryX" xmlns:XSLT="http://www.w3.org/1999/XSL/Transform/compile">
<meta:form-name>2022-CORE-Sales</meta:form-name>
<meta:document-id>shared_ownership_sales_log4</meta:document-id>
<meta:owner-user-id>e29c492473446dca4d50224f2bb7cf965a261d6f</meta:owner-user-id>
<meta:owner-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:owner-institution-id>
<meta:managing-institution-id>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</meta:managing-institution-id>
<meta:created-date>2023-02-21T11:48:28.255968Z</meta:created-date>
<meta:modified-date>2023-02-22T11:00:06.575832Z</meta:modified-date>
<meta:status>submitted-valid</meta:status>
<meta:reporting-year>2022</meta:reporting-year>
<meta:upload-method>Manual Entry</meta:upload-method>
<meta:schema assert-valid="true"/>
<meta:rules assert-valid="true"/>
</meta:metadata>
<Group>
<Qdp>Yes</Qdp>
<CompletionDate>2023-01-17</CompletionDate>
<PurchaserCode>Shared ownership example</PurchaserCode>
<Ownership>1 Yes - a shared ownership scheme</Ownership>
<Q16SaleType>2 Shared Ownership</Q16SaleType>
<Q30SaleType/>
<Q38SaleType/>
<Q38OtherSale/>
<company>2 No</company>
<LiveInBuyer>1 Yes</LiveInBuyer>
<joint>2 No</joint>
<JointMore/>
<PartAPurchaser>2 Yes</PartAPurchaser>
</Group>
<Group>
<Q11Bedrooms override-field="">2</Q11Bedrooms>
<Q12PropertyType>1 Flat or maisonette</Q12PropertyType>
<Q13BuildingType>1 Purpose built</Q13BuildingType>
<Q14Postcode override-field="">SW1A 1AA</Q14Postcode>
<Q14PropertyLocation>Westminster</Q14PropertyLocation>
<Q14ONSLACode>E09000033</Q14ONSLACode>
<Q15Wheelchair>3 Don&#x2019;t know</Q15Wheelchair>
</Group>
<Group>
<P1Age>30</P1Age>
<P1Sex override-field="">Male</P1Sex>
<P1Eco>1 Full Time - 30 hours or more a week</P1Eco>
<P1Eth>2 White: Irish</P1Eth>
<P1Nat>18 United Kingdom</P1Nat>
<P2Age/>
<P2Sex override-field=""/>
<P2Rel/>
<P2Eco/>
<P3Age/>
<P3Sex override-field=""/>
<P3Rel/>
<P3Eco/>
<P4Age/>
<P4Sex override-field=""/>
<P4Rel/>
<P4Eco/>
<P5Age/>
<P5Sex override-field=""/>
<P5Rel/>
<P5Eco/>
<P6Age/>
<P6Sex override-field=""/>
<P6Rel/>
<P6Eco/>
<P7Age/>
<P7Sex override-field=""/>
<P7Rel/>
<P7Eco/>
<P8Age/>
<P8Sex override-field=""/>
<P8Rel/>
<P8Eco/>
<LiveInBuyer1>1 Yes</LiveInBuyer1>
<LiveInBuyer2/>
<LiveInOther/>
</Group>
<Group>
<P2Partner>0</P2Partner>
<P3Partner>0</P3Partner>
<P4Partner>0</P4Partner>
<P5Partner>0</P5Partner>
<P6Partner>0</P6Partner>
<P7Partner>0</P7Partner>
<P8Partner>0</P8Partner>
<Partner>0</Partner>
<P2AgeT>0</P2AgeT>
<P3AgeT>0</P3AgeT>
<P4AgeT>0</P4AgeT>
<P5AgeT>0</P5AgeT>
<P6AgeT>0</P6AgeT>
<P7AgeT>0</P7AgeT>
<P8AgeT>0</P8AgeT>
<P2SexT>0</P2SexT>
<P3SexT>0</P3SexT>
<P4SexT>0</P4SexT>
<P5SexT>0</P5SexT>
<P6SexT>0</P6SexT>
<P7SexT>0</P7SexT>
<P8SexT>0</P8SexT>
<P2RelT>0</P2RelT>
<P3RelT>0</P3RelT>
<P4RelT>0</P4RelT>
<P5RelT>0</P5RelT>
<P6RelT>0</P6RelT>
<P7RelT>0</P7RelT>
<P8RelT>0</P8RelT>
<P2EcoT>0</P2EcoT>
<P3EcoT>0</P3EcoT>
<P4EcoT>0</P4EcoT>
<P5EcoT>0</P5EcoT>
<P6EcoT>0</P6EcoT>
<P7EcoT>0</P7EcoT>
<P8EcoT>0</P8EcoT>
<P2HHoldT>0</P2HHoldT>
<P3HHoldT>0</P3HHoldT>
<P4HHoldT>0</P4HHoldT>
<P5HHoldT>0</P5HHoldT>
<P6HHoldT>0</P6HHoldT>
<P7HHoldT>0</P7HHoldT>
<P8HHoldT>0</P8HHoldT>
<P2PAge>0</P2PAge>
<P3PAge>0</P3PAge>
<P4PAge>0</P4PAge>
<P5PAge>0</P5PAge>
<P6PAge>0</P6PAge>
<P7PAge>0</P7PAge>
<P8PAge>0</P8PAge>
<PAGE/>
<Q30Answer/>
<P2Other>0</P2Other>
<P3Other>0</P3Other>
<P4Other>0</P4Other>
<P5Other>0</P5Other>
<P6Other>0</P6Other>
<P7Other>0</P7Other>
<P8Other>0</P8Other>
<Other>0</Other>
<P2RRefused>0</P2RRefused>
<P3RRefused>0</P3RRefused>
<P4RRefused>0</P4RRefused>
<P5RRefused>0</P5RRefused>
<P6RRefused>0</P6RRefused>
<P7RRefused>0</P7RRefused>
<P8RRefused>0</P8RRefused>
<TotRRefused>0</TotRRefused>
<CALCMORT>76000</CALCMORT>
<MORTGAGEUSED>1</MORTGAGEUSED>
<IM1>47000</IM1>
<IM2>0</IM2>
<IMT>235000</IMT>
<MortMultiple>0</MortMultiple>
<Form>300204</Form>
</Group>
<Group>
<minmaxP11/>
<minmaxP12/>
<minmaxP13/>
<minmaxP14/>
<minmaxP15/>
<minmaxP16/>
<minmaxP17/>
<minmaxP18/>
<minmaxP1T/>
<minmaxP19/>
<minmaxP10/>
<minmaxP21/>
<minmaxP22/>
<minmaxP23/>
<minmaxP24/>
<minmaxP25/>
<minmaxP26/>
<minmaxP27/>
<minmaxP28/>
<minmaxP2T/>
<minmaxP29/>
<minmaxP20/>
<Q16CHK>1</Q16CHK>
<Q30CHK>0</Q30CHK>
<Q38CHK>0</Q38CHK>
<SalesCHKT>1</SalesCHKT>
<Q23CHK>1</Q23CHK>
<Q16typeCHK>2</Q16typeCHK>
<Q16Q23>3</Q16Q23>
<DAY>17</DAY>
<MONTH>1</MONTH>
<YEAR>2023</YEAR>
<HODAY>6</HODAY>
<HOMONTH>9</HOMONTH>
<HOYEAR>2022</HOYEAR>
<EXDAY>8</EXDAY>
<EXMONTH>1</EXMONTH>
<EXYEAR>2023</EXYEAR>
<PPOSTC1>SW14</PPOSTC1>
<PPOSTC2>7QP</PPOSTC2>
<PCODE1>SW1A</PCODE1>
<PCODE2>1AA</PCODE2>
<NOINT/>
</Group>
<Group>
<Q6PrevTenure>2 Private registered provider (PRP) or housing association tenant</Q6PrevTenure>
<Q7Postcode override-field="">SW14 7QP</Q7Postcode>
<Q7UnknownPostcode/>
<Q7PrevLocation>Richmond-upon-Thames</Q7PrevLocation>
<Q7ONSLACode>E09000027</Q7ONSLACode>
<PREGYRHA>Yes</PREGYRHA>
<PREGORHA/>
<PREGLA/>
<PREGHBA/>
<PREGOTHER/>
</Group>
<Group>
<ArmedF>8 Don&#x2019;t know</ArmedF>
<LeftArmedF/>
<ARMEDFORCESSPOUSE/>
<Disability>2 No</Disability>
<Q10Wheelchair override-field="">2 No</Q10Wheelchair>
</Group>
<Group>
<P1IncKnown>1 Yes</P1IncKnown>
<Q2Person1Income>47000</Q2Person1Income>
<Q2Person1Mortgage>1 Yes</Q2Person1Mortgage>
<P2IncKnown/>
<Q2Person2Income/>
<Q2Person2MortApplication/>
<Q2a>4 Don&#x2019;t know</Q2a>
<savingsKnown>1 Yes</savingsKnown>
<Q3Savings override-field="true">89000</Q3Savings>
<Q4PrevOwnedProperty>1 Yes</Q4PrevOwnedProperty>
</Group>
<Group>
<!-- replace with commented options to test in the future -->
<!-- <Q16aProplen2/> -->
<Q16aProplen2>1</Q16aProplen2>
<Q17aStaircase>2 No</Q17aStaircase>
<PercentBought override-field=""/>
<PercentOwns>30</PercentOwns>
<Q17Resale>2 No</Q17Resale>
<Q18ContractExchange override-field="">2023-01-08</Q18ContractExchange>
<Q18PracticalCompletion override-field="">2022-09-06</Q18PracticalCompletion>
<Q19Rehoused>2 No</Q19Rehoused>
<Q20Bedrooms/>
<Q21PropertyType/>
<PrevRentType/>
<Q22PurchasePrice override-field="true">550000</Q22PurchasePrice>
<Q23Equity override-field="">30</Q23Equity>
<MortgageUsedSO>1 Yes</MortgageUsedSO>
<Q24Mortgage override-field="">76000</Q24Mortgage>
<Q24aMortgageLender>Nationwide</Q24aMortgageLender>
<Q24b>33</Q24b>
<Q25Borrowing>2 No</Q25Borrowing>
<Q26CashDeposit override-field="">89000</Q26CashDeposit>
<Q27SocialHomeBuy/>
<Q28MonthlyRent>912.00</Q28MonthlyRent>
<Q29MonthlyCharges></Q29MonthlyCharges>
</Group>
<Group>
<Q16aProplensec2/>
<Q31PurchasePrice override-field=""/>
<Q32Reductions override-field=""/>
<Q33Discount override-field=""/>
<MortgageUsedDO/>
<Q34Mortgage override-field=""/>
<Q34a/>
<Q34b/>
<Q35Borrowing/>
<Q36CashDeposit/>
<Q37MonthlyCharges/>
</Group>
<Group>
<Q40PurchasePrice override-field=""/>
<MortgageUsedOS/>
<Q41Mortgage override-field=""/>
<Q41aMortgageLender/>
<Q41b/>
<Q42Borrowing/>
<Q43CashDeposit override-field=""/>
</Group>
<Group>
<HHMEMB>1</HHMEMB>
<TOTADULT>1</TOTADULT>
<TOTCHILD>0</TOTCHILD>
</Group>
<Group>
<HHTYPE>3 = 1 adult</HHTYPE>
</Group>
<Group>
<DerSaleType>2 Shared Ownership</DerSaleType>
</Group>
<Group>
<HHTYPEP1A>1</HHTYPEP1A>
<HHTYPEP2A>0</HHTYPEP2A>
<HHTYPEP3A>0</HHTYPEP3A>
<HHTYPEP4A>0</HHTYPEP4A>
<HHTYPEP5A>0</HHTYPEP5A>
<HHTYPEP6A>0</HHTYPEP6A>
<HHTYPEP7A>0</HHTYPEP7A>
<HHTYPEP8A>0</HHTYPEP8A>
<TADULT>1</TADULT>
<HHTYPEP1E>0</HHTYPEP1E>
<HHTYPEP2E>0</HHTYPEP2E>
<HHTYPEP3E>0</HHTYPEP3E>
<HHTYPEP4E>0</HHTYPEP4E>
<HHTYPEP5E>0</HHTYPEP5E>
<HHTYPEP6E>0</HHTYPEP6E>
<HHTYPEP7E>0</HHTYPEP7E>
<HHTYPEP8E>0</HHTYPEP8E>
<TELDER>0</TELDER>
<HHTYPEP1C>0</HHTYPEP1C>
<HHTYPEP2C>0</HHTYPEP2C>
<HHTYPEP3C>0</HHTYPEP3C>
<HHTYPEP4C>0</HHTYPEP4C>
<HHTYPEP5C>0</HHTYPEP5C>
<HHTYPEP6C>0</HHTYPEP6C>
<HHTYPEP7C>0</HHTYPEP7C>
<HHTYPEP8C>0</HHTYPEP8C>
<TCHILD>0</TCHILD>
<Q8av>1</Q8av>
<Q8bv>0</Q8bv>
<Q8cv>0</Q8cv>
<Q8dv>0</Q8dv>
<Q8ev>0</Q8ev>
<Q8Validate>1</Q8Validate>
</Group>
<Group>
<PLOACODE/>
<OACODE/>
<GOVREG>E12000007</GOVREG>
<OWNINGORGID>1</OWNINGORGID>
<OWNINGORGNAME>1 Test</OWNINGORGNAME>
<HCNUM>655</HCNUM>
</Group>
</Group>

25
spec/fixtures/imports/schemes/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml vendored

@ -1,25 +0,0 @@
<scheme:scheme xmlns:scheme="dclg:scheme">
<scheme:id>0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e</scheme:id>
<scheme:name id-field="Y">Location 1</scheme:name>
<scheme:local-authority-name>134</scheme:local-authority-name>
<scheme:postcode>S44 6EJ</scheme:postcode>
<scheme:required>true</scheme:required>
<scheme:sensitive>false</scheme:sensitive>
<scheme:total-units>5</scheme:total-units>
<scheme:sp-grant>True</scheme:sp-grant>
<scheme:scheme-type>7</scheme:scheme-type>
<scheme:unit-type>6</scheme:unit-type>
<scheme:reg-home-type>1</scheme:reg-home-type>
<scheme:support-type>2</scheme:support-type>
<scheme:mobility-type>A</scheme:mobility-type>
<scheme:intended-stay>P</scheme:intended-stay>
<scheme:client-group-1>M</scheme:client-group-1>
<scheme:client-group-2/>
<scheme:start-date>1900-01-01</scheme:start-date>
<scheme:end-date>2050-12-31</scheme:end-date>
<scheme:mgmtgroup>6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d</scheme:mgmtgroup>
<scheme:status>Approved</scheme:status>
<scheme:visible-id>10</scheme:visible-id>
<scheme:user-stamp>1</scheme:user-stamp>
<scheme:date-stamp>08:12.0</scheme:date-stamp>
</scheme:scheme>

23
spec/fixtures/imports/schemes/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml vendored

@ -1,23 +0,0 @@
<scheme:scheme xmlns:scheme="dclg:scheme">
<scheme:id>0bb3836b70b4dd9903263d5a764a5c45b964a89d</scheme:id>
<scheme:name id-field="Y">Location 2</scheme:name>
<scheme:local-authority-name>134</scheme:local-authority-name>
<scheme:postcode>NG19 8SW</scheme:postcode>
<scheme:required>false</scheme:required>
<scheme:sensitive>false</scheme:sensitive>
<scheme:total-units>11</scheme:total-units>
<scheme:scheme-type>7</scheme:scheme-type>
<scheme:unit-type>6</scheme:unit-type>
<scheme:reg-home-type>1</scheme:reg-home-type>
<scheme:support-type>2</scheme:support-type>
<scheme:mobility-type>W</scheme:mobility-type>
<scheme:sp-grant>False</scheme:sp-grant>
<scheme:intended-stay>P</scheme:intended-stay>
<scheme:client-group-1>M</scheme:client-group-1>
<scheme:client-group-2/>
<scheme:start-date>2014-04-07</scheme:start-date>
<scheme:end-date/>
<scheme:mgmtgroup>6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d</scheme:mgmtgroup>
<scheme:status>Approved</scheme:status>
<scheme:visible-id>001</scheme:visible-id>
</scheme:scheme>

13
spec/fixtures/imports/user/10c887710550844e2551b3e0fb88dc9b4a8a642b.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>10c887710550844e2551b3e0fb88dc9b4a8a642b</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe@gov.uk</user:email>
<user:user-type>Data Protection Officer</user:user-type>
<user:active>true</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>None</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

19
spec/fixtures/imports/user/80d9b73aa1c88b6e5c36ee49be9050b923b4a1bb.xml vendored

@ -1,19 +0,0 @@
<user xmlns="dclg:user">
<id>80d9b73aa1c88b6e5c36ee49be9050b923b4a1bb</id>
<user-name>Jane Doe</user-name>
<institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</institution>
<user-stamp>1158 1158</user-stamp>
<active>true</active>
<user-type>Data Provider</user-type>
<association-site-id />
<e-core-download>false</e-core-download>
<raw-data-download>false</raw-data-download>
<licence>false</licence>
<contact-priority-id>None</contact-priority-id>
<email>jane.doe@gov.uk</email>
<password>REDACTED</password>
<full-name>Jane Doe</full-name>
<telephone-no>01111 000000</telephone-no>
<deleted>false</deleted>
<date-deactivated>2021-09-28Z</date-deactivated>
</user>

13
spec/fixtures/imports/user/9ed81a262215a1634f0809effa683e38924d8bcb.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>9ed81a262215a1634f0809effa683e38924d8bcb</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe2@gov.uk</user:email>
<user:user-type>Data Provider</user:user-type>
<user:active>false</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>None</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

13
spec/fixtures/imports/user/b7829b1a5dfb68bb1e01c08445830c0add40907c.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>b7829b1a5dfb68bb1e01c08445830c0add40907c</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe@gov.uk</user:email>
<user:user-type>Private Data Downloader</user:user-type>
<user:active>true</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>None</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

13
spec/fixtures/imports/user/d4729b1a5dfb68bb1e01c08445830c0add40907c.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>d4729b1a5dfb68bb1e01c08445830c0add40907c</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe@gov.uk</user:email>
<user:user-type>Co-ordinator</user:user-type>
<user:active>true</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>Key Performance Contact</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

13
spec/fixtures/imports/user/d6717836154cd9a58f9e2f1d3077e3ab81e07613.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>d6717836154cd9a58f9e2f1d3077e3ab81e07613</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe@gov.uk</user:email>
<user:user-type>Co-ordinator</user:user-type>
<user:active>true</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>eCORE Contact</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

13
spec/fixtures/imports/user/fc7625a02b24ae16162aa63ae7cb33feeec0c373.xml vendored

@ -1,13 +0,0 @@
<user:user xmlns:user="dclg:user">
<user:id>fc7625a02b24ae16162aa63ae7cb33feeec0c373</user:id>
<user:password>xxx</user:password>
<user:full-name>John Doe</user:full-name>
<user:user-name>john.doe</user:user-name>
<user:institution>7c5bd5fb549c09a2c55d7cb90d7ba84927e64618</user:institution>
<user:email>john.doe@gov.uk</user:email>
<user:user-type>Data Provider</user:user-type>
<user:active>true</user:active>
<user:deleted>false</user:deleted>
<user:contact-priority-id>None</user:contact-priority-id>
<user:telephone-no>02012345678</user:telephone-no>
</user:user>

76
spec/lib/tasks/blank_migrated_soctenant_values_spec.rb

@ -1,76 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "blank_migrated_soctenant_values" do
describe ":blank_migrated_soctenant_values", type: :task do
subject(:task) { Rake::Task["blank_migrated_soctenant_values"] }
before do
Rake.application.rake_require("tasks/blank_migrated_soctenant_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:sales_log) { create(:sales_log, :completed, :shared_ownership, values_updated_at: nil) }
it "blanks soctenant (and subsequent questions) values from relevant migrated logs" do
sales_log.old_id = "404"
sales_log.frombeds = nil
sales_log.fromprop = 0 # don't know
sales_log.socprevten = 10 # don't know
sales_log.soctenant = 0 # don't know
sales_log.save!
task.invoke
sales_log.reload
expect(sales_log.soctenant).to eq(nil)
expect(sales_log.frombeds).to eq(nil)
expect(sales_log.fromprop).to eq(nil)
expect(sales_log.socprevten).to eq(nil)
expect(sales_log.values_updated_at).not_to be_nil
end
context "with 2022 logs" do
around do |example|
Timecop.freeze(Time.zone.local(2022, 5, 5)) do
Singleton.__init__(FormHandler)
example.run
end
end
it "does not blank soctenant (and subsequent questions) values" do
sales_log.old_id = "404"
sales_log.frombeds = nil
sales_log.fromprop = 0 # don't know
sales_log.socprevten = 10 # don't know
sales_log.soctenant = 0 # don't know
sales_log.saledate = Time.zone.local(2022, 5, 5)
sales_log.save!
task.invoke
sales_log.reload
expect(sales_log.soctenant).to eq(0)
expect(sales_log.frombeds).to eq(nil)
expect(sales_log.fromprop).to eq(0)
expect(sales_log.socprevten).to eq(10)
expect(sales_log.values_updated_at).to be_nil
end
end
it "does not blank soctenant (and subsequent questions) values from non imported logs" do
sales_log.old_id = nil
sales_log.frombeds = nil
sales_log.fromprop = 0 # don't know
sales_log.socprevten = 10 # don't know
sales_log.soctenant = 0 # don't know
sales_log.save!
task.invoke
sales_log.reload
expect(sales_log.soctenant).to eq(0)
expect(sales_log.frombeds).to eq(nil)
expect(sales_log.fromprop).to eq(0)
expect(sales_log.socprevten).to eq(10)
expect(sales_log.values_updated_at).to be_nil
end
end
end
end

165
spec/lib/tasks/confirm_charges_soft_validations_spec.rb

@ -1,165 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "confirm_charges_soft_validations" do
describe ":confirm_charges_soft_validations", type: :task do
subject(:task) { Rake::Task["confirm_charges_soft_validations"] }
before do
Rake.application.rake_require("tasks/confirm_charges_soft_validations")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed) }
it "confirms scharge value check for lettings logs with scharge over soft max" do
lettings_log.scharge = 404
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.scharge_value_check).to eq(0)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not confirm scharge value check for lettings logs with scharge under soft max" do
lettings_log.scharge = 40
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.scharge_value_check).to eq(nil)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm scharge value check for in progress logs" do
lettings_log.update!(scharge: 404, reason: nil, status: "in_progress")
expect(lettings_log.reload.status).to eq("in_progress")
task.invoke
expect(lettings_log.reload.scharge_value_check).to eq(nil)
expect(lettings_log.status).to eq("in_progress")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm scharge value check if it already is confirmed" do
lettings_log.update!(scharge: 404, scharge_value_check: 0)
expect(lettings_log.reload.status).to eq("completed")
task.invoke
expect { task.invoke }.not_to change(lettings_log.reload, :scharge_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm scharge value check for 2021 logs" do
lettings_log.scharge = 404
lettings_log.skip_update_status = true
lettings_log.startdate = Time.zone.local(2021, 4, 1)
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
expect { task.invoke }.not_to change(lettings_log.reload, :scharge_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
it "confirms pscharge value check for lettings logs with pscharge over soft max" do
lettings_log.pscharge = 204
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.pscharge_value_check).to eq(0)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not confirm pscharge value check for lettings logs with pscharge under soft max" do
lettings_log.pscharge = 40
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.pscharge_value_check).to eq(nil)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm pscharge value check for in progress logs" do
lettings_log.update!(pscharge: 204, reason: nil, status: "in_progress")
expect(lettings_log.reload.status).to eq("in_progress")
task.invoke
expect(lettings_log.reload.pscharge_value_check).to eq(nil)
expect(lettings_log.status).to eq("in_progress")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm pscharge value check if it already is confirmed" do
lettings_log.update!(pscharge: 204, pscharge_value_check: 0)
expect(lettings_log.reload.status).to eq("completed")
task.invoke
expect { task.invoke }.not_to change(lettings_log.reload, :pscharge_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm pscharge value check for 2021 logs" do
lettings_log.pscharge = 204
lettings_log.skip_update_status = true
lettings_log.startdate = Time.zone.local(2021, 4, 1)
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
expect { task.invoke }.not_to change(lettings_log.reload, :pscharge_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
it "confirms supcharg value check for lettings logs with supcharg over soft max" do
lettings_log.supcharg = 204
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.supcharg_value_check).to eq(0)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not confirm supcharg value check for lettings logs with supcharg under soft max" do
lettings_log.supcharg = 40
lettings_log.skip_update_status = true
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
task.invoke
expect(lettings_log.reload.supcharg_value_check).to eq(nil)
expect(lettings_log.status).to eq("completed")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm supcharg value check for in progress logs" do
lettings_log.update!(supcharg: 204, reason: nil, status: "in_progress")
expect(lettings_log.reload.status).to eq("in_progress")
task.invoke
expect(lettings_log.reload.supcharg_value_check).to eq(nil)
expect(lettings_log.status).to eq("in_progress")
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm supcharg value check if it already is confirmed" do
lettings_log.update!(supcharg: 204, supcharg_value_check: 0)
expect(lettings_log.reload.status).to eq("completed")
task.invoke
expect { task.invoke }.not_to change(lettings_log.reload, :supcharg_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not confirm supcharg value check for 2021 logs" do
lettings_log.supcharg = 204
lettings_log.skip_update_status = true
lettings_log.startdate = Time.zone.local(2021, 4, 1)
lettings_log.save!(validate: false)
lettings_log.skip_update_status = nil
expect { task.invoke }.not_to change(lettings_log.reload, :supcharg_value_check)
expect(lettings_log.values_updated_at).to be_nil
end
end
end
end

56
spec/lib/tasks/correct_has_other_client_group_values_spec.rb

@ -1,56 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_has_other_client_group_values" do
describe ":correct_has_other_client_group_values", type: :task do
subject(:task) { Rake::Task["correct_has_other_client_group_values"] }
before do
Rake.application.rake_require("tasks/correct_has_other_client_group_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:scheme) { create(:scheme, secondary_client_group: nil) }
before do
scheme.has_other_client_group = nil
scheme.save!(validate: false)
end
context "and the scheme is marked confirmed" do
it "updates schemes with secondary_client_group to have has_other_client_group 1 (yes)" do
scheme.secondary_client_group = "G"
scheme.save!(validate: false)
task.invoke
expect(scheme.reload.has_other_client_group).to eq("Yes")
end
it "updates schemes without secondary_client_group to have has_other_client_group 0 (no)" do
task.invoke
expect(scheme.reload.has_other_client_group).to eq("No")
end
end
context "and the scheme is not marked confirmed" do
before do
scheme.confirmed = false
scheme.save!(validate: false)
end
it "does not update schemes with secondary_client_group" do
scheme.secondary_client_group = "G"
scheme.save!(validate: false)
task.invoke
expect(scheme.reload.has_other_client_group).to eq(nil)
end
it "does not update schemes without secondary_client_group" do
task.invoke
expect(scheme.reload.has_other_client_group).to eq(nil)
end
end
end
end
end

52
spec/lib/tasks/correct_incref_values_spec.rb

@ -1,52 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_incref_values" do
describe ":correct_incref_values", type: :task do
subject(:task) { Rake::Task["correct_incref_values"] }
before do
Rake.application.rake_require("tasks/correct_incref_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed) }
it "updates lettings logs with net_income_known 0 (yes) to have incref 0 (no)" do
lettings_log.update!(net_income_known: 0, incref: nil)
task.invoke
expect(lettings_log.reload.incref).to eq(0)
end
it "updates lettings logs with net_income_known 1 (no) to have incref 2 (don't know)" do
lettings_log.update!(net_income_known: 1, incref: nil)
task.invoke
expect(lettings_log.reload.incref).to eq(2)
end
it "updates lettings logs with net_income_known 2 (prefers not to say) to have incref 1 (yes)" do
lettings_log.update!(net_income_known: 2, incref: nil)
task.invoke
expect(lettings_log.reload.incref).to eq(1)
end
it "skips validations for previous years" do
lettings_log.update!(net_income_known: 2, incref: nil)
lettings_log.startdate = Time.zone.local(2021, 3, 3)
lettings_log.save!(validate: false)
task.invoke
expect(lettings_log.reload.incref).to eq(1)
end
it "updates updated_at value" do
lettings_log.updated_at = Time.zone.local(2021, 3, 3)
lettings_log.save!(validate: false)
expect(lettings_log.updated_at.to_date).to eq(Time.zone.local(2021, 3, 3))
task.invoke
expect(lettings_log.reload.updated_at.to_date).to eq(Time.zone.today)
end
end
end
end

52
spec/lib/tasks/correct_location_admin_district_spec.rb

@ -1,52 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_location_admin_district" do
describe ":correct_location_admin_district", type: :task do
subject(:task) { Rake::Task["correct_location_admin_district"] }
before do
Rake.application.rake_require("tasks/correct_location_admin_district")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:scheme) { create(:scheme) }
let!(:location) { create(:location, postcode: "A11AA", location_code: "E06000009", location_admin_district: nil, startdate: nil) }
it "updates location with missing location admin district and marks it as complete" do
expect(location.confirmed).to eq(false)
task.invoke
location.reload
scheme.reload
expect(location.confirmed).to eq(true)
expect(location.location_admin_district).to eq("Blackpool")
end
it "does not mark location as complete if other fields are missing" do
location.update!(units: nil)
expect(location.confirmed).to eq(false)
task.invoke
location.reload
scheme.reload
expect(location.confirmed).to eq(false)
expect(location.location_admin_district).to eq("Blackpool")
end
it "does not override existing location admin district" do
location.location_admin_district = "Babergh"
location.save!(validate: false)
task.invoke
expect(location.reload.location_admin_district).to eq("Babergh")
end
it "does not set location admin district if it cannot be found" do
location.location_code = "123"
location.save!(validate: false)
task.invoke
expect(location.reload.location_admin_district).to eq(nil)
end
end
end
end

80
spec/lib/tasks/correct_min_age_values_spec.rb

@ -1,80 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_min_age_values" do
describe ":correct_min_age_values", type: :task do
subject(:task) { Rake::Task["correct_min_age_values"] }
before do
Rake.application.rake_require("tasks/correct_min_age_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed) }
it "updates lettings logs with age2..8 0 to have age2..8 1" do
lettings_log.hhmemb = 8
lettings_log.age2_known = 0
lettings_log.age2 = 0
lettings_log.age3_known = 0
lettings_log.age3 = 0
lettings_log.age4_known = 0
lettings_log.age4 = 0
lettings_log.age5_known = 0
lettings_log.age5 = 0
lettings_log.age6_known = 0
lettings_log.age6 = 0
lettings_log.age7_known = 0
lettings_log.age7 = 0
lettings_log.age8_known = 0
lettings_log.age8 = 0
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.age2).to eq(1)
expect(lettings_log.age3).to eq(1)
expect(lettings_log.age4).to eq(1)
expect(lettings_log.age5).to eq(1)
expect(lettings_log.age6).to eq(1)
expect(lettings_log.age7).to eq(1)
expect(lettings_log.age8).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not update valid age2..8 values" do
lettings_log.hhmemb = 8
lettings_log.age2_known = 0
lettings_log.age2 = 2
lettings_log.age3_known = 0
lettings_log.age3 = 4
lettings_log.age4_known = 0
lettings_log.age4 = 2
lettings_log.age5_known = 0
lettings_log.age5 = 2
lettings_log.age6_known = 0
lettings_log.age6 = 3
lettings_log.age7_known = 0
lettings_log.age7 = 6
lettings_log.age8_known = 0
lettings_log.age8 = 20
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.age2).to eq(2)
expect(lettings_log.age3).to eq(4)
expect(lettings_log.age4).to eq(2)
expect(lettings_log.age5).to eq(2)
expect(lettings_log.age6).to eq(3)
expect(lettings_log.age7).to eq(6)
expect(lettings_log.age8).to eq(20)
expect(lettings_log.values_updated_at).to be_nil
end
end
end
end

67
spec/lib/tasks/correct_ppcodenk_values_spec.rb

@ -1,67 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "correct_ppcodenk_values" do
describe ":correct_ppcodenk_values", type: :task do
subject(:task) { Rake::Task["correct_ppcodenk_values"] }
before do
Rake.application.rake_require("tasks/correct_ppcodenk_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed) }
it "updates lettings logs with ppcodenk 0 to have ppcodenk 1" do
lettings_log.update!(ppcodenk: 0)
task.invoke
expect(lettings_log.reload.ppcodenk).to eq(1)
end
it "updates lettings logs with ppcodenk 1 to have ppcodenk 0" do
lettings_log.update!(ppcodenk: 1)
task.invoke
expect(lettings_log.reload.ppcodenk).to eq(0)
end
it "does not update lettings logs with ppcodenk nil" do
lettings_log.update!(ppcodenk: nil)
task.invoke
expect(lettings_log.reload.ppcodenk).to eq(nil)
end
context "with multiple lettings logs" do
let(:lettings_log_2) { create(:lettings_log, :completed) }
let(:lettings_log_3) { create(:lettings_log, :completed) }
it "only updates each log once" do
lettings_log.update!(ppcodenk: nil)
lettings_log_2.update!(ppcodenk: 0)
lettings_log_3.update!(ppcodenk: 1)
task.invoke
expect(lettings_log.reload.ppcodenk).to eq(nil)
expect(lettings_log_2.reload.ppcodenk).to eq(1)
expect(lettings_log_3.reload.ppcodenk).to eq(0)
end
end
it "does not update updated_at value" do
lettings_log.updated_at = Time.zone.local(2021, 3, 3)
lettings_log.save!(validate: false)
expect(lettings_log.updated_at.to_date).to eq(Time.zone.local(2021, 3, 3))
task.invoke
expect(lettings_log.updated_at.to_date).to eq(Time.zone.local(2021, 3, 3))
end
it "skips validations for previous years" do
lettings_log.update!(ppcodenk: 1)
lettings_log.startdate = Time.zone.local(2021, 3, 3)
lettings_log.save!(validate: false)
task.invoke
expect(lettings_log.reload.ppcodenk).to eq(0)
end
end
end
end

338
spec/lib/tasks/data_import_field_spec.rb

@ -1,338 +0,0 @@
require "rails_helper"
require "rake"
describe "data_import_field imports" do
context "with rake core:lettings_data_import_field", type: :task do
subject(:task) { Rake::Task["core:lettings_data_import_field"] }
let(:instance_name) { "paas_import_instance" }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:env_config_service) { instance_double(Configuration::EnvConfigurationService) }
let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) }
before do
Rake.application.rake_require("tasks/data_import_field")
Rake::Task.define_task(:environment)
task.reenable
allow(Storage::S3Service).to receive(:new).and_return(storage_service)
allow(Configuration::EnvConfigurationService).to receive(:new).and_return(env_config_service)
allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service)
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name)
allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy")
allow(Imports::LettingsLogsFieldImportService).to receive(:new).and_return(import_service)
end
context "when importing a lettings log field" do
let(:import_service) { instance_double(Imports::LettingsLogsFieldImportService) }
let(:fixture_path) { "spec/fixtures/imports/logs" }
let(:archive_service) { instance_double(Storage::ArchiveService) }
before do
allow(import_service).to receive(:update_field)
allow(Storage::ArchiveService).to receive(:new).and_return(archive_service)
allow(archive_service).to receive(:folder_present?).with("logs").and_return(true)
end
context "and we update the tenancycode field" do
let(:field) { "tenancycode" }
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable exists" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the lettings_allocation fields" do
let(:field) { "lettings_allocation" }
it "updates the logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the major repairs fields" do
let(:field) { "major_repairs" }
it "updates the logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the offered fields" do
let(:field) { "offered" }
it "updates the logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the address fields" do
let(:field) { "address" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the reason field" do
let(:field) { "reason" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update homeless fields" do
let(:field) { "homeless" }
it "updates the logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the created_by field" do
let(:field) { "created_by" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the sex_and_relat fields" do
let(:field) { "sex_and_relat" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the referral (for general needs) field" do
let(:field) { "general_needs_referral" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the person_details field" do
let(:field) { "person_details" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the childrens_care_referral field" do
let(:field) { "childrens_care_referral" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the old_form_id field" do
let(:field) { "old_form_id" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the postcode_full field" do
let(:field) { "postcode_full" }
it "updates the 2023 logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/logs")
expect(Imports::LettingsLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
it "raises an exception if no parameters are provided" do
expect { task.invoke }.to raise_error(/Usage/)
end
it "raises an exception if a single parameter is provided" do
expect { task.invoke("one_parameter") }.to raise_error(/Usage/)
end
it "raises an exception if the field is not supported" do
expect { task.invoke("random_field", "my_path") }.to raise_error("Field random_field cannot be updated by lettings_data_import_field")
end
end
end
context "with rake core:sales_data_import_field", type: :task do
subject(:task) { Rake::Task["core:sales_data_import_field"] }
let(:instance_name) { "paas_import_instance" }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:env_config_service) { instance_double(Configuration::EnvConfigurationService) }
let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) }
before do
Rake.application.rake_require("tasks/data_import_field")
Rake::Task.define_task(:environment)
task.reenable
allow(Storage::S3Service).to receive(:new).and_return(storage_service)
allow(Configuration::EnvConfigurationService).to receive(:new).and_return(env_config_service)
allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service)
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name)
allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy")
allow(Imports::SalesLogsFieldImportService).to receive(:new).and_return(import_service)
end
context "when importing a sales log field" do
let(:import_service) { instance_double(Imports::SalesLogsFieldImportService) }
let(:fixture_path) { "spec/fixtures/imports/sales_logs" }
let(:archive_service) { instance_double(Storage::ArchiveService) }
before do
allow(import_service).to receive(:update_field)
allow(Storage::ArchiveService).to receive(:new).and_return(archive_service)
allow(archive_service).to receive(:folder_present?).with("logs").and_return(true)
end
context "and we update the owning_organisation_id field" do
let(:field) { "owning_organisation_id" }
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable exists" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the old_form_id field" do
let(:field) { "old_form_id" }
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable exists" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
context "and we update the created_by field" do
let(:field) { "created_by" }
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable exists" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
it "updates the logs from the given XML file when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).to receive(:get_file_io).with("spec/fixtures/imports/sales_logs")
expect(Imports::SalesLogsFieldImportService).to receive(:new).with(archive_service)
expect(import_service).to receive(:update_field).with(field, "logs")
task.invoke(field, fixture_path)
end
end
it "raises an exception if no parameters are provided" do
expect { task.invoke }.to raise_error(/Usage/)
end
it "raises an exception if a single parameter is provided" do
expect { task.invoke("one_parameter") }.to raise_error(/Usage/)
end
it "raises an exception if the field is not supported" do
expect { task.invoke("random_field", "my_path") }.to raise_error("Field random_field cannot be updated by sales_data_import_field")
end
end
end
end

191
spec/lib/tasks/data_import_spec.rb

@ -1,191 +0,0 @@
require "rails_helper"
require "rake"
describe "data import", type: :task do
let(:instance_name) { "paas_import_instance" }
let(:env_config_service) { instance_double(Configuration::EnvConfigurationService) }
let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) }
let(:storage_service) { instance_double(Storage::S3Service) }
describe "core:data_import" do
subject(:task) { Rake::Task["core:data_import"] }
before do
Rake.application.rake_require("tasks/data_import")
Rake::Task.define_task(:environment)
task.reenable
allow(Storage::S3Service).to receive(:new).and_return(storage_service)
allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service)
allow(Configuration::EnvConfigurationService).to receive(:new).and_return(env_config_service)
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name)
allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy")
end
context "when importing organisation data" do
let(:type) { "organisation" }
let(:import_service) { instance_double(Imports::OrganisationImportService) }
let(:fixture_path) { "spec/fixtures/imports/organisations" }
before do
allow(Imports::OrganisationImportService).to receive(:new).and_return(import_service)
end
it "creates an organisation from the given XML file when the VCAP_SERVICES environment variable exists" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::OrganisationImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_organisations).with(fixture_path)
task.invoke(type, fixture_path)
end
it "creates an organisation from the given XML file when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(Imports::OrganisationImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_organisations).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing user data" do
let(:type) { "user" }
let(:import_service) { instance_double(Imports::UserImportService) }
let(:fixture_path) { "spec/fixtures/imports/users" }
before do
allow(Imports::UserImportService).to receive(:new).and_return(import_service)
end
it "creates a user from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::UserImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_users).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing data protection confirmation data" do
let(:type) { "data-protection-confirmation" }
let(:import_service) { instance_double(Imports::DataProtectionConfirmationImportService) }
let(:fixture_path) { "spec/fixtures/imports/data_protection_confirmations" }
before do
allow(Imports::DataProtectionConfirmationImportService).to receive(:new).and_return(import_service)
end
it "creates an organisation from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::DataProtectionConfirmationImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_data_protection_confirmations).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing organisation rent period data" do
let(:type) { "organisation-rent-periods" }
let(:import_service) { instance_double(Imports::OrganisationRentPeriodImportService) }
let(:fixture_path) { "spec/fixtures/imports/organisation_rent_periods" }
before do
allow(Imports::OrganisationRentPeriodImportService).to receive(:new).and_return(import_service)
end
it "creates an organisation la from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::OrganisationRentPeriodImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_organisation_rent_periods).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing lettings logs" do
let(:type) { "lettings-logs" }
let(:import_service) { instance_double(Imports::LettingsLogsImportService) }
let(:fixture_path) { "spec/fixtures/imports/lettings_logs" }
before do
allow(Imports::LettingsLogsImportService).to receive(:new).and_return(import_service)
end
it "creates lettings logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::LettingsLogsImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_logs).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing sales logs" do
let(:type) { "sales-logs" }
let(:import_service) { instance_double(Imports::SalesLogsImportService) }
let(:fixture_path) { "spec/fixtures/imports/sales_logs" }
before do
allow(Imports::SalesLogsImportService).to receive(:new).and_return(import_service)
end
it "creates sales logs from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::SalesLogsImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_logs).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing scheme data" do
let(:type) { "scheme" }
let(:import_service) { instance_double(Imports::SchemeImportService) }
let(:fixture_path) { "spec/fixtures/imports/schemes" }
before do
allow(Imports::SchemeImportService).to receive(:new).and_return(import_service)
end
it "creates a scheme from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::SchemeImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_schemes).with(fixture_path)
task.invoke(type, fixture_path)
end
end
context "when importing scheme location data" do
let(:type) { "scheme-location" }
let(:import_service) { instance_double(Imports::SchemeLocationImportService) }
let(:fixture_path) { "spec/fixtures/imports/organisations" }
before do
allow(Imports::SchemeLocationImportService).to receive(:new).and_return(import_service)
end
it "creates a scheme location from the given XML file" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::SchemeLocationImportService).to receive(:new).with(storage_service)
expect(import_service).to receive(:create_scheme_locations).with(fixture_path)
task.invoke(type, fixture_path)
end
end
it "raises an exception if no parameters are provided" do
expect { task.invoke }.to raise_error(/Usage/)
end
it "raises an exception if a single parameter is provided" do
expect { task.invoke("one_parameter") }.to raise_error(/Usage/)
end
it "raises an exception if the type is not supported" do
expect { task.invoke("unknown_type", "my_path") }.to raise_error(/Type unknown_type is not supported/)
end
end
end

144
spec/lib/tasks/full_import_spec.rb

@ -1,144 +0,0 @@
require "rails_helper"
require "rake"
describe "full import", type: :task do
let(:instance_name) { "paas_import_instance" }
let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) }
let(:env_config_service) { instance_double(Configuration::EnvConfigurationService) }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:orgs_list) { "Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1.zip,0,0,0,0\norg2,2.zip,0,0,0,0" }
before do
allow(Storage::S3Service).to receive(:new).and_return(storage_service)
allow(storage_service).to receive(:write_file).and_return(nil)
allow(storage_service).to receive(:get_file_io).and_return(orgs_list)
allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service)
allow(Configuration::EnvConfigurationService).to receive(:new).and_return(env_config_service)
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name)
end
describe "import:generate_reports" do
subject(:task) { Rake::Task["import:generate_reports"] }
before do
Rake.application.rake_require("tasks/full_import")
Rake::Task.define_task(:environment)
task.reenable
end
context "when generating report" do
let(:import_report_service) { instance_double(Imports::ImportReportService) }
before do
allow(Imports::ImportReportService).to receive(:new).and_return(import_report_service)
end
it "creates a report using given organisation csv when the VCAP_SERVICES environment variable exists" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy")
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::ImportReportService).to receive(:new).with(storage_service, CSV.parse(orgs_list, headers: true))
expect(import_report_service).to receive(:create_reports).with("some_name")
task.invoke("some_name")
end
it "creates a report using given organisation csv when the VCAP_SERVICES environment variable does not exist" do
allow(ENV).to receive(:[]).with("VCAP_SERVICES")
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(Imports::ImportReportService).to receive(:new).with(storage_service, CSV.parse(orgs_list, headers: true))
expect(import_report_service).to receive(:create_reports).with("some_name")
task.invoke("some_name")
end
end
end
describe "import:generate_missing_answers_report" do
subject(:task) { Rake::Task["import:generate_missing_answers_report"] }
before do
Rake.application.rake_require("tasks/full_import")
Rake::Task.define_task(:environment)
task.reenable
end
context "when generating a missing answers report" do
let(:import_report_service) { instance_double(Imports::ImportReportService) }
before do
allow(Imports::ImportReportService).to receive(:new).and_return(import_report_service)
allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy")
end
it "creates a missing answers report" do
expect(Storage::S3Service).to receive(:new).with(paas_config_service, instance_name)
expect(Imports::ImportReportService).to receive(:new).with(storage_service, nil)
expect(import_report_service).to receive(:generate_missing_answers_report).with("some_name")
task.invoke("some_name")
end
end
end
describe "import:initial" do
subject(:task) { Rake::Task["import:initial"] }
let(:archive_service) { instance_double(Storage::ArchiveService) }
before do
Rake.application.rake_require("tasks/full_import")
Rake::Task.define_task(:environment)
task.reenable
end
context "when calling the initial import" do
before do
allow(Storage::ArchiveService).to receive(:new).and_return(archive_service)
allow(archive_service).to receive(:folder_present?).and_return(false)
allow(Imports::OrganisationImportService).to receive(:new).and_return(instance_double(Imports::OrganisationImportService))
allow(Imports::SchemeImportService).to receive(:new).and_return(instance_double(Imports::SchemeImportService))
allow(Imports::SchemeLocationImportService).to receive(:new).and_return(instance_double(Imports::SchemeLocationImportService))
allow(Imports::UserImportService).to receive(:new).and_return(instance_double(Imports::UserImportService))
allow(Imports::DataProtectionConfirmationImportService).to receive(:new).and_return(instance_double(Imports::DataProtectionConfirmationImportService))
allow(Imports::OrganisationRentPeriodImportService).to receive(:new).and_return(instance_double(Imports::OrganisationRentPeriodImportService))
end
it "does not write a report if there were no errors" do
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).not_to receive(:write_file).with("some_name_1_initial.log", "")
expect(storage_service).not_to receive(:write_file).with("some_name_2_initial.log", "")
task.invoke("some_name.csv")
end
end
end
describe "import:logs" do
subject(:task) { Rake::Task["import:logs"] }
let(:archive_service) { instance_double(Storage::ArchiveService) }
before do
Rake.application.rake_require("tasks/full_import")
Rake::Task.define_task(:environment)
task.reenable
end
context "when calling the logs import" do
before do
allow(Storage::ArchiveService).to receive(:new).and_return(archive_service)
allow(archive_service).to receive(:folder_present?).and_return(false)
allow(Imports::LettingsLogsImportService).to receive(:new).and_return(instance_double(Imports::LettingsLogsImportService))
allow(Imports::SalesLogsImportService).to receive(:new).and_return(instance_double(Imports::SalesLogsImportService))
end
it "does not write a report if there were no errors" do
expect(Storage::S3Service).to receive(:new).with(env_config_service, instance_name)
expect(storage_service).not_to receive(:write_file).with("some_name_1_logs.log", "")
expect(storage_service).not_to receive(:write_file).with("some_name_2_logs.log", "")
task.invoke("some_name.csv")
end
end
end
end

132
spec/lib/tasks/recalculate_irproduct_values_spec.rb

@ -1,132 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "recalculate_irproduct_values" do
describe ":recalculate_irproduct_values", type: :task do
subject(:task) { Rake::Task["recalculate_irproduct_values"] }
before do
Rake.application.rake_require("tasks/recalculate_irproduct_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed, values_updated_at: nil) }
it "updates irproduct to nil if it's set to 1 but rent type is not 3, 4 or 5" do
lettings_log.irproduct = 1
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(nil)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to nil if it's set to 2 but rent type is not 3, 4 or 5" do
lettings_log.irproduct = 2
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(nil)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to nil if it's set to 3 but rent type is not 3, 4 or 5" do
lettings_log.irproduct = 3
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(nil)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 1 if it's set to nil but rent type is 3" do
lettings_log.irproduct = nil
lettings_log.rent_type = 3
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 1 if it's set to something else but rent type is 3" do
lettings_log.irproduct = 2
lettings_log.rent_type = 3
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 2 if it's set to nil but rent type is 4" do
lettings_log.irproduct = nil
lettings_log.rent_type = 4
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(2)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 2 if it's set to something else but rent type is 4" do
lettings_log.irproduct = 1
lettings_log.rent_type = 4
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(2)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 3 if it's set to nil but rent type is 5" do
lettings_log.irproduct = nil
lettings_log.rent_type = 5
lettings_log.irproduct_other = "other"
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(3)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates irproduct to 3 if it's set to something else but rent type is 5" do
lettings_log.irproduct = 2
lettings_log.rent_type = 5
lettings_log.irproduct_other = "other"
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(3)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not update irproduct if rent_type is not 3, 4 or 5 and irproduct is nil" do
lettings_log.irproduct = nil
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(nil)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not update irproduct if a different validation is triggering" do
lettings_log.irproduct = 2
lettings_log.rent_type = 5
lettings_log.postcode_full = "invalid"
lettings_log.save!(validate: false)
expect(Rails.logger).to receive(:info).with("Could not update irproduct for LettingsLog #{lettings_log.id}")
task.invoke
lettings_log.reload
expect(lettings_log.irproduct).to eq(2)
expect(lettings_log.values_updated_at).to be_nil
end
end
end
end

100
spec/lib/tasks/recalculate_lar_values_spec.rb

@ -1,100 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "recalculate_lar_values" do
describe ":recalculate_lar_values", type: :task do
subject(:task) { Rake::Task["recalculate_lar_values"] }
before do
Rake.application.rake_require("tasks/recalculate_lar_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed, values_updated_at: nil) }
it "updates lar to nil if it's not afordable rent or london afordable rent and lar is 1 but does not set it to export" do
lettings_log.lar = 1
lettings_log.rent_type = 3
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(nil)
expect(lettings_log.values_updated_at).to be_nil
end
it "updates lar to nil if it's not afordable rent or london afordable rent and lar is 2 but does not set it to export" do
lettings_log.lar = 2
lettings_log.rent_type = 4
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(nil)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not update lar if it's not london afordable rent or affordable rent and lar is nil" do
lettings_log.lar = nil
lettings_log.rent_type = 3
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(nil)
expect(lettings_log.values_updated_at).to be_nil
end
it "updates lar to 1 if it's london afordable rent and lar is currently nil" do
lettings_log.lar = nil
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates lar to 1 if it's london afordable rent and lar is currently 2" do
lettings_log.lar = 2
lettings_log.rent_type = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates lar to 2 if it's afordable rent and lar is currently nil" do
lettings_log.lar = nil
lettings_log.rent_type = 1
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(2)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates lar to 2 if it's afordable rent and lar is currently 1" do
lettings_log.lar = 1
lettings_log.rent_type = 1
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(2)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not update lar if a different validation is triggering" do
lettings_log.lar = 1
lettings_log.rent_type = 1
lettings_log.postcode_full = "invalid"
lettings_log.save!(validate: false)
expect(Rails.logger).to receive(:info).with("Could not update lar for LettingsLog #{lettings_log.id}")
task.invoke
lettings_log.reload
expect(lettings_log.lar).to eq(1)
expect(lettings_log.values_updated_at).to be_nil
end
end
end
end

84
spec/lib/tasks/recalculate_refused_values_spec.rb

@ -1,84 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "recalculate_refused_values" do
describe ":recalculate_refused_values", type: :task do
subject(:task) { Rake::Task["recalculate_refused_values"] }
before do
Rake.application.rake_require("tasks/recalculate_refused_values")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:lettings_log) { create(:lettings_log, :completed, values_updated_at: nil) }
it "updates refused value to 1 if details for person are not known" do
lettings_log.refused = 0
lettings_log.details_known_2 = 1
lettings_log.hhmemb = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.refused).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "does not update refused value if details known is nil" do
lettings_log.update!(details_known_2: nil, hhmemb: 2)
lettings_log.refused = 0
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.refused).to eq(0)
expect(lettings_log.values_updated_at).to be_nil
end
it "does not update refused value if details are known" do
lettings_log.refused = 0
lettings_log.details_known_2 = 0
lettings_log.hhmemb = 2
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.refused).to eq(0)
expect(lettings_log.values_updated_at).to be_nil
end
it "updates refused value to 1 if details for any person are not known" do
lettings_log.refused = 0
lettings_log.details_known_2 = 0
lettings_log.details_known_3 = 0
lettings_log.details_known_4 = 0
lettings_log.details_known_5 = 0
lettings_log.details_known_6 = 1
lettings_log.details_known_7 = 0
lettings_log.details_known_8 = 0
lettings_log.hhmemb = 8
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.refused).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
it "updates values updated at if refused is already set to 1 but some details are unknown" do
lettings_log.refused = 1
lettings_log.details_known_2 = 0
lettings_log.details_known_3 = 0
lettings_log.details_known_4 = 0
lettings_log.details_known_5 = 0
lettings_log.details_known_6 = 1
lettings_log.details_known_7 = 0
lettings_log.details_known_8 = 0
lettings_log.hhmemb = 8
lettings_log.save!(validate: false)
task.invoke
lettings_log.reload
expect(lettings_log.refused).to eq(1)
expect(lettings_log.values_updated_at).not_to be_nil
end
end
end
end

54
spec/lib/tasks/remove_placeholder_deactivations_spec.rb

@ -1,54 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "data_cleanup" do
describe ":remove_placeholder_deactivations", type: :task do
subject(:task) { Rake::Task["data_cleanup:remove_placeholder_deactivations"] }
before do
Rake.application.rake_require("tasks/remove_placeholder_deactivations")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
context "with location model" do
let(:locations) { create_list(:location, 3) }
let!(:placeholder_location_deactivation) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2031, 1, 1), location: locations[0]) }
let!(:placeholder_location_deactivation_two) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2031, 1, 1), location: locations[1]) }
let!(:valid_location_deactivation) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2030, 12, 31), location: locations[2]) }
it "removes location_deactivation_period with date on or after 2031/01/01" do
expect(Rails.logger).to receive(:info).with("Removed 2 location deactivation periods")
expect { task.invoke("location") }.to change(LocationDeactivationPeriod, :count).by(-2)
expect { placeholder_location_deactivation.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { placeholder_location_deactivation_two.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { valid_location_deactivation.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
end
end
context "with scheme model" do
let(:schemes) { create_list(:scheme, 3) }
let!(:placeholder_scheme_deactivation) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2031, 1, 1), scheme: schemes[0]) }
let!(:placeholder_scheme_deactivation_two) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2031, 1, 1), scheme: schemes[1]) }
let!(:valid_scheme_deactivation) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2030, 12, 31), scheme: schemes[2]) }
it "removes scheme_deactivation_period with date on or after 2031/01/01" do
expect(Rails.logger).to receive(:info).with("Removed 2 scheme deactivation periods")
expect { task.invoke("scheme") }.to change(SchemeDeactivationPeriod, :count).by(-2)
expect { placeholder_scheme_deactivation.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { placeholder_scheme_deactivation_two.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { valid_scheme_deactivation.reload }.not_to raise_error(ActiveRecord::RecordNotFound)
end
end
it "raises an error when no model is given" do
expect { task.invoke(nil) }.to raise_error(RuntimeError, "Usage: rake data_cleanup:remove_placeholder_deactivations['model_name']")
end
it "logs an error when wrong model is given" do
expect { task.invoke("fake_model") }.to raise_error(RuntimeError, "Deactivations for fake_model cannot be deleted")
end
end
end
end

65
spec/lib/tasks/squish_names_spec.rb

@ -1,65 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "squish_names" do
describe ":squish_names", type: :task do
subject(:task) { Rake::Task["squish_names"] }
before do
Rake.application.rake_require("tasks/squish_names")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
let!(:scheme) { create(:scheme) }
let!(:location) { create(:location) }
let!(:user) { create(:user) }
let!(:organisation) { create(:organisation) }
it "updates names with multiple spaces to only have one" do
scheme.service_name = "test test"
location.name = "test test test"
user.name = "test test"
organisation.name = "test test test"
scheme.save!(validate: false)
location.save!(validate: false)
user.save!(validate: false)
organisation.save!(validate: false)
task.invoke
scheme.reload
location.reload
user.reload
organisation.reload
expect(scheme.service_name).to eq("test test")
expect(location.name).to eq("test test test")
expect(user.name).to eq("test test")
expect(organisation.name).to eq("test test test")
end
it "does not update names without multiple spaces" do
scheme.service_name = "test test"
location.name = "test test test"
user.name = "test test"
organisation.name = "test test test"
scheme.save!(validate: false)
location.save!(validate: false)
user.save!(validate: false)
organisation.save!(validate: false)
task.invoke
scheme.reload
location.reload
user.reload
organisation.reload
expect(scheme.service_name).to eq("test test")
expect(location.name).to eq("test test test")
expect(user.name).to eq("test test")
expect(organisation.name).to eq("test test test")
end
end
end
end

97
spec/services/imports/data_protection_confirmation_import_service_spec.rb

@ -1,97 +0,0 @@
require "rails_helper"
RSpec.describe Imports::DataProtectionConfirmationImportService do
let(:fixture_directory) { "spec/fixtures/imports/dataprotect" }
let(:old_org_id) { "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618" }
let(:old_id) { old_org_id }
let(:import_file) { File.open("#{fixture_directory}/#{old_id}.xml") }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
context "when importing data protection confirmations" do
subject(:import_service) { described_class.new(storage_service, logger) }
before do
allow(storage_service)
.to receive(:list_files)
.and_return(["data_protection_directory/#{old_id}.xml"])
allow(storage_service)
.to receive(:get_file_io)
.with("data_protection_directory/#{old_id}.xml")
.and_return(import_file)
end
context "when the organisation in the import file doesn't exist in the system" do
it "does not create a data protection confirmation" do
expect(logger).to receive(:error).with("Organisation must exist")
import_service.create_data_protection_confirmations("data_protection_directory")
end
end
context "when the organisation does exist" do
let!(:organisation) { create(:organisation, :without_dpc, old_org_id:, phone: "123") }
context "when a data protection officer with matching name does not exists for the organisation" do
it "creates an inactive data protection officer" do
expect { import_service.create_data_protection_confirmations("data_protection_directory") }
.to change(User, :count).by(1)
data_protection_officer = User.find_by(organisation:, is_dpo: true)
expect(data_protection_officer.confirmed_at).not_to be_nil
expect(data_protection_officer.active).to be false
end
it "successfully create a data protection confirmation record with the expected data", :aggregate_failures do
import_service.create_data_protection_confirmations("data_protection_directory")
confirmation = Organisation.find_by(old_org_id:).data_protection_confirmation
expect(confirmation.confirmed).to be_truthy
expect(confirmation.data_protection_officer.name).to eq("John Doe")
expect(confirmation.data_protection_officer_name).to eq("John Doe")
expect(confirmation.organisation_address).to eq("2 Marsham Street, London, SW1P 4DF")
expect(confirmation.organisation_name).to eq("DLUHC")
expect(confirmation.organisation_phone_number).to eq("123")
expect(Time.zone.local_to_utc(confirmation.signed_at)).to eq(Time.utc(2018, 0o6, 0o5, 10, 36, 49))
end
end
context "when a data protection officer with matching name already exists for the organisation" do
let!(:data_protection_officer) do
create(:user, :data_protection_officer, name: "John Doe", organisation:)
end
it "successfully creates a data protection confirmation record with the expected data" do
import_service.create_data_protection_confirmations("data_protection_directory")
confirmation = Organisation.find_by(old_org_id:).data_protection_confirmation
expect(confirmation.data_protection_officer.id).to eq(data_protection_officer.id)
expect(confirmation.confirmed).to be_truthy
expect(confirmation.data_protection_officer.name).to eq(data_protection_officer.name)
expect(confirmation.data_protection_officer_name).to eq(data_protection_officer.name)
expect(confirmation.data_protection_officer_email).to eq(data_protection_officer.email)
expect(confirmation.organisation_address).to eq("2 Marsham Street, London, SW1P 4DF")
expect(confirmation.organisation_name).to eq("DLUHC")
expect(confirmation.organisation_phone_number).to eq("123")
expect(Time.zone.local_to_utc(confirmation.signed_at)).to eq(Time.utc(2018, 0o6, 0o5, 10, 36, 49))
end
context "when the data protection record has already been imported previously" do
before do
create(
:data_protection_confirmation,
organisation:,
data_protection_officer:,
old_org_id:,
old_id:,
)
end
it "logs that the record already exists" do
expect(logger).to receive(:warn)
import_service.create_data_protection_confirmations("data_protection_directory")
end
end
end
end
end
end

185
spec/services/imports/import_report_service_spec.rb

@ -1,185 +0,0 @@
require "rails_helper"
RSpec.describe Imports::ImportReportService do
subject(:report_service) { described_class.new(storage_service, institutions_csv) }
let(:storage_service) { instance_double(Storage::S3Service) }
describe "#generate_missing_data_coordinators_report" do
context "when all organisations have data coordinators" do
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") }
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) }
before do
create(:user, :data_coordinator, organisation:)
end
it "writes an empty organisations without a data coordinators report" do
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n")
report_service.generate_missing_data_coordinators_report("report_suffix.csv")
end
end
context "when some organisations have no data coordinators" do
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") }
let!(:organisation2) { create(:organisation, old_visible_id: "2", name: "org2") }
let!(:organisation3) { create(:organisation, old_visible_id: "3", name: "org3") }
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3\norg2,2,5,6,5,7\norg3,3,5,6,5,7", headers: true) }
before do
create(:user, :data_coordinator, organisation:)
end
it "writes an empty organisations without a data coordinators report" do
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n#{organisation2.id},2,org2\n#{organisation3.id},3,org3\n")
report_service.generate_missing_data_coordinators_report("report_suffix.csv")
end
end
context "when organisation has an inactive data coordinator" do
let!(:organisation) { create(:organisation, old_visible_id: "1", name: "org1") }
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) }
before do
create(:user, :data_coordinator, organisation:, active: false)
end
it "includes that organisation in the data coordinators report" do
expect(storage_service).to receive(:write_file).with("OrganisationsWithoutDataCoordinators_report_suffix.csv", "\uFEFFOrganisation ID,Old Organisation ID,Organisation Name\n#{organisation.id},1,org1\n")
report_service.generate_missing_data_coordinators_report("report_suffix.csv")
end
end
end
describe "#generate_logs_report" do
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3\norg2,2,5,6,5,7", headers: true) }
before do
org1 = create(:organisation, old_visible_id: "1", name: "org1")
create(:organisation, old_visible_id: "2", name: "org2")
create(:lettings_log, :completed, owning_organisation: org1, old_id: "fake_old_id")
create(:lettings_log, :completed, owning_organisation: org1, old_id: nil)
create(:sales_log, :completed, owning_organisation: org1, old_id: "fake_sales_old_id")
create(:sales_log, :completed, owning_organisation: org1, old_id: nil)
end
it "generates a report with imported logs" do
expect(storage_service).to receive(:write_file).with("MigratedLogsReport_report_suffix.csv", "\uFEFFInstitution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs,New Completed lettings logs,New In Progress lettings logs,New Completed sales logs,New In Progress sales logs\norg1,1,2,1,4,3,1,0,1,0\norg2,2,5,6,5,7,0,0,0,0\n")
report_service.generate_logs_report("report_suffix.csv")
end
end
describe "#generate_unassigned_logs_report" do
context "when there is no unassigned user (all the logs have ben assigned)" do
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) }
it "writes an empty unassigned logs report" do
expect(storage_service).to receive(:write_file).with("UnassignedLogsReport_report_suffix.csv", "\uFEFFOwning Organisation ID,Old Owning Organisation ID,Managing Organisation ID,Old Managing Organisation ID,Log ID,Old Log ID,Tenancy code,Purchaser code\n")
report_service.generate_unassigned_logs_report("report_suffix.csv")
end
end
context "when some logs have been added to Unassigned user" do
let(:organisation) { create(:organisation, old_org_id: "1", name: "org1") }
let(:organisation2) { create(:organisation, old_org_id: "2", name: "org2") }
let(:unassigned_user) { create(:user, name: "Unassigned", organisation:) }
let(:institutions_csv) { CSV.parse("Institution name,Id,Old Completed lettings logs,Old In progress lettings logs,Old Completed sales logs,Old In progress sales logs\norg1,1,2,1,4,3", headers: true) }
let!(:lettings_log) { create(:lettings_log, owning_organisation: organisation, managing_organisation: organisation2, created_by: unassigned_user, tenancycode: "tenancycode", old_id: "12") }
let!(:sales_log) { create(:sales_log, owning_organisation: organisation, created_by: unassigned_user, purchid: "purchid", old_id: "23") }
before do
create(:organisation_relationship, parent_organisation: organisation, child_organisation: organisation2)
create(:sales_log, owning_organisation: organisation, created_by: unassigned_user, purchid: "purchid_2", old_id: nil)
create(:lettings_log, owning_organisation: organisation, managing_organisation: organisation2, created_by: unassigned_user, tenancycode: "tenancycode_2", old_id: nil)
end
it "writes a report with all unassigned logs" do
expect(storage_service).to receive(:write_file).with("UnassignedLogsReport_report_suffix.csv", "\uFEFFOwning Organisation ID,Old Owning Organisation ID,Managing Organisation ID,Old Managing Organisation ID,Log ID,Old Log ID,Tenancy code,Purchaser code\n#{organisation.id},1,#{organisation2.id},2,#{lettings_log.id},12,tenancycode,\n#{organisation.id},1,,,#{sales_log.id},23,,purchid\n")
report_service.generate_unassigned_logs_report("report_suffix.csv")
end
end
end
describe "#generate_missing_answers_report" do
context "when there are in progress imported lettings logs" do
let(:institutions_csv) { nil }
let(:expected_content) { File.read("spec/fixtures/files/imported_lettings_logs_missing_answers_report.csv") }
let(:expected_answers_examples_content) { File.read("spec/fixtures/files/imported_lettings_logs_missing_answers_examples.csv") }
before do
create_list(:lettings_log, 10, :completed, age1_known: nil) do |log, i|
log.old_form_id = "100#{i}"
log.old_id = "old_id_age1_known_#{i}"
log.save!
expected_answers_examples_content.sub!("{id#{i}}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id#{i}}", log.owning_organisation_id.to_s)
end
create_list(:lettings_log, 4, :completed, beds: nil) do |log, i|
log.old_form_id = "200#{i}"
log.old_id = "old_id_beds_#{i}"
expected_answers_examples_content.sub!("{id2_#{i}}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id2_#{i}}", log.owning_organisation_id.to_s)
log.save!
end
create(:lettings_log, :completed, age1_known: nil, beds: nil, old_form_id: "300", old_id: "beds_and_age") do |log|
expected_answers_examples_content.sub!("{id}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id}", log.owning_organisation_id.to_s)
end
create_list(:lettings_log, 2, :completed, age1_known: nil)
end
xit "generates a csv with expected missing fields" do
expect(storage_service).to receive(:write_file).with("MissingAnswersReportLettingsLog_report_suffix.csv", "#{expected_content}")
expect(storage_service).to receive(:write_file).with("MissingAnswersExamplesLettingsLog_report_suffix.csv", "#{expected_answers_examples_content}")
expect(storage_service).to receive(:write_file).with("MissingAnswersReportSalesLog_report_suffix.csv", "\uFEFFMissing answers,Total number of affected logs\n")
expect(storage_service).to receive(:write_file).with("MissingAnswersExamplesSalesLog_report_suffix.csv", "\uFEFFMissing answers,Organisation ID,Log ID,Old Form ID,Old Log ID\n")
report_service.generate_missing_answers_report("report_suffix")
end
end
context "when there are in progress imported sales logs" do
let(:institutions_csv) { nil }
let(:expected_content) { File.read("spec/fixtures/files/imported_lettings_logs_missing_answers_report.csv") }
let(:expected_answers_examples_content) { File.read("spec/fixtures/files/imported_lettings_logs_missing_answers_examples.csv") }
before do
create_list(:sales_log, 10, :completed, age1_known: nil) do |log, i|
log.old_id = "old_id_age1_known_#{i}"
log.old_form_id = "100#{i}"
log.save!
expected_answers_examples_content.sub!("{id#{i}}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id#{i}}", log.owning_organisation_id.to_s)
end
create_list(:sales_log, 4, :completed, beds: nil) do |log, i|
log.old_id = "old_id_beds_#{i}"
log.old_form_id = "200#{i}"
expected_answers_examples_content.sub!("{id2_#{i}}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id2_#{i}}", log.owning_organisation_id.to_s)
log.save!
end
create(:sales_log, :completed, age1_known: nil, beds: nil, old_id: "beds_and_age", old_form_id: "300") do |log|
expected_answers_examples_content.sub!("{id}", log.id.to_s)
expected_answers_examples_content.sub!("{org_id}", log.owning_organisation_id.to_s)
end
create_list(:sales_log, 2, :completed, age1_known: nil)
end
xit "generates a csv with expected missing fields" do
expect(storage_service).to receive(:write_file).with("MissingAnswersReportLettingsLog_report_suffix.csv", "\uFEFFMissing answers,Total number of affected logs\n")
expect(storage_service).to receive(:write_file).with("MissingAnswersExamplesLettingsLog_report_suffix.csv", "\uFEFFMissing answers,Organisation ID,Log ID,Old Form ID,Old Log ID\n")
expect(storage_service).to receive(:write_file).with("MissingAnswersReportSalesLog_report_suffix.csv", "#{expected_content}")
expect(storage_service).to receive(:write_file).with("MissingAnswersExamplesSalesLog_report_suffix.csv", "#{expected_answers_examples_content}")
report_service.generate_missing_answers_report("report_suffix")
end
end
end
end

1573
spec/services/imports/lettings_logs_field_import_service_spec.rb

File diff suppressed because it is too large Load Diff

2160
spec/services/imports/lettings_logs_import_service_spec.rb

File diff suppressed because it is too large Load Diff

153
spec/services/imports/organisation_import_service_spec.rb

@ -1,153 +0,0 @@
require "rails_helper"
RSpec.describe Imports::OrganisationImportService do
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logs_string) { StringIO.new }
let(:logger) { MultiLogger.new(logs_string) }
let(:folder_name) { "organisations" }
let(:filenames) { %w[my_folder/my_file1.xml my_folder/my_file2.xml] }
let(:fixture_directory) { "spec/fixtures/imports/institution" }
def create_organisation_file(fixture_directory, visible_id, filename, namespace_given, name = nil)
file = File.open("#{fixture_directory}/#{filename}.xml")
doc = Nokogiri::XML(file)
if namespace_given
doc.at_xpath("//institution:visible-id").content = visible_id if visible_id
doc.at_xpath("//institution:name").content = name if name
else
doc.at_xpath("//dclg:visible-id", { "dclg" => "dclg:institution" }).content = visible_id if visible_id
doc.at_xpath("//dclg:name", { "dclg" => "dclg:institution" }).content = name if name
end
StringIO.new(doc.to_xml)
end
context "when importing organisations" do
subject(:import_service) { described_class.new(storage_service) }
before do
allow(storage_service).to receive(:list_files)
.and_return(filenames)
allow(storage_service).to receive(:get_file_io)
.with(filenames[0])
.and_return(create_organisation_file(fixture_directory, 1, "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618", true))
allow(storage_service).to receive(:get_file_io)
.with(filenames[1])
.and_return(create_organisation_file(fixture_directory, 2, "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618", true))
end
it "successfully create an organisation with the expected data" do
import_service.create_organisations(folder_name)
organisation = Organisation.find_by(old_visible_id: "1")
expect(organisation.name).to eq("HA Ltd")
expect(organisation.provider_type).to eq("PRP")
expect(organisation.phone).to eq("xxxxxxxx")
expect(organisation.holds_own_stock).to be_truthy
expect(organisation.active).to be_truthy
# expect(organisation.old_association_type).to eq() string VS integer
# expect(organisation.software_supplier_id).to eq() boolean VS string
expect(organisation.housing_management_system).to eq("") # Need examples
expect(organisation.choice_based_lettings).to be_falsey
expect(organisation.common_housing_register).to be_falsey
expect(organisation.choice_allocation_policy).to be_falsey
expect(organisation.cbl_proportion_percentage).to be_nil # Need example
expect(organisation.enter_affordable_logs).to be_truthy
expect(organisation.owns_affordable_logs).to be_truthy # owns_affordable_rent
expect(organisation.housing_registration_no).to eq("LH9999")
expect(organisation.general_needs_units).to eq(1104)
expect(organisation.supported_housing_units).to eq(217)
expect(organisation.unspecified_units).to eq(0)
expect(organisation.unspecified_units).to eq(0)
expect(organisation.old_org_id).to eq("7c5bd5fb549c09z2c55d9cb90d7ba84927e64618")
expect(organisation.old_visible_id).to eq("1")
end
it "successfully create multiple organisations" do
expect(storage_service).to receive(:list_files).with(folder_name)
expect(storage_service).to receive(:get_file_io).with(filenames[0]).ordered
expect(storage_service).to receive(:get_file_io).with(filenames[1]).ordered
expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(2)
expect(Organisation).to exist(old_visible_id: "1")
expect(Organisation).to exist(old_visible_id: "2")
end
end
context "when importing organisations twice" do
subject(:import_service) { described_class.new(storage_service, logger) }
before do
allow(storage_service).to receive(:list_files).and_return([filenames[0]])
allow(storage_service).to receive(:get_file_io).and_return(
create_organisation_file(fixture_directory, 1, "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618", true),
create_organisation_file(fixture_directory, 1, "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618", true, "my_new_organisation"),
)
end
it "successfully create an organisation the first time, and does not update it" do
expect(storage_service).to receive(:list_files).with(folder_name).twice
expect(storage_service).to receive(:get_file_io).with(filenames[0]).twice
expect(logger).to receive(:warn).once.and_call_original
expect(Rails.logger).to receive(:warn).with("Organisation my_new_organisation is already present with old visible ID 1, skipping.")
expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(1)
expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(0)
expect(logs_string.string).not_to include("Organisation my_new_organisation is already present with old visible ID 1, skipping.")
expect(Organisation).to exist(old_visible_id: "1", name: "HA Ltd")
end
end
context "when importing organisations with no namespace" do
subject(:import_service) { described_class.new(storage_service) }
before do
allow(storage_service).to receive(:list_files)
.and_return(filenames)
allow(storage_service).to receive(:get_file_io)
.with(filenames[0])
.and_return(create_organisation_file(fixture_directory, 1, "8c5bd5fb549c09a2c55d7cb90d7ba84927e64618", false))
allow(storage_service).to receive(:get_file_io)
.with(filenames[1])
.and_return(create_organisation_file(fixture_directory, 2, "8c5bd5fb549c09a2c55d7cb90d7ba84927e64618", false))
end
it "successfully create an organisation with the expected data" do
import_service.create_organisations(folder_name)
organisation = Organisation.find_by(old_visible_id: "1")
expect(organisation.name).to eq("HA Ltd")
expect(organisation.provider_type).to eq("PRP")
expect(organisation.phone).to eq("xxxxxxxx")
expect(organisation.holds_own_stock).to be_truthy
expect(organisation.active).to be_truthy
# expect(organisation.old_association_type).to eq() string VS integer
# expect(organisation.software_supplier_id).to eq() boolean VS string
expect(organisation.housing_management_system).to eq("") # Need examples
expect(organisation.choice_based_lettings).to be_falsey
expect(organisation.common_housing_register).to be_falsey
expect(organisation.choice_allocation_policy).to be_falsey
expect(organisation.cbl_proportion_percentage).to be_nil # Need example
expect(organisation.enter_affordable_logs).to be_truthy
expect(organisation.owns_affordable_logs).to be_truthy # owns_affordable_rent
expect(organisation.housing_registration_no).to eq("LH9999")
expect(organisation.general_needs_units).to eq(1104)
expect(organisation.supported_housing_units).to eq(217)
expect(organisation.unspecified_units).to eq(0)
expect(organisation.unspecified_units).to eq(0)
expect(organisation.old_org_id).to eq("8c5bd5fb549c09z2c55d9cb90d7ba84927e64618")
expect(organisation.old_visible_id).to eq("1")
end
it "successfully create multiple organisations" do
expect(storage_service).to receive(:list_files).with(folder_name)
expect(storage_service).to receive(:get_file_io).with(filenames[0]).ordered
expect(storage_service).to receive(:get_file_io).with(filenames[1]).ordered
expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(2)
expect(Organisation).to exist(old_visible_id: "1")
expect(Organisation).to exist(old_visible_id: "2")
end
end
end

42
spec/services/imports/organisation_rent_period_import_service_spec.rb

@ -1,42 +0,0 @@
require "rails_helper"
RSpec.describe Imports::OrganisationRentPeriodImportService do
let(:fixture_directory) { "spec/fixtures/imports/rent-period" }
let(:old_org_id) { "44026acc7ed5c29516b26f2a5deb639e5e37966d" }
let(:old_id) { "ebd22326d33e389e9f1bfd546979d2c05f9e68d6" }
let(:import_file) { File.open("#{fixture_directory}/#{old_id}.xml") }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
context "when importing organisation rent periods" do
subject(:import_service) { described_class.new(storage_service, logger) }
before do
allow(storage_service)
.to receive(:list_files)
.and_return(["organisation_rent_period_directory/#{old_id}.xml"])
allow(storage_service)
.to receive(:get_file_io)
.with("organisation_rent_period_directory/#{old_id}.xml")
.and_return(import_file)
end
context "when the organisation in the import file doesn't exist in the system" do
it "does not create an organisation rent period record" do
expect(logger).to receive(:error).with(/Organisation must exist/)
import_service.create_organisation_rent_periods("organisation_rent_period_directory")
end
end
context "when the organisation does exist" do
before do
FactoryBot.create(:organisation, old_org_id:)
end
it "successfully create an organisation rent period record with the expected data" do
import_service.create_organisation_rent_periods("organisation_rent_period_directory")
expect(Organisation.find_by(old_org_id:).organisation_rent_periods.pluck("rent_period")).to eq([1])
end
end
end
end

238
spec/services/imports/sales_logs_field_import_service_spec.rb

@ -1,238 +0,0 @@
require "rails_helper"
RSpec.describe Imports::SalesLogsFieldImportService do
subject(:import_service) { described_class.new(storage_service, logger) }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:fixture_directory) { "spec/fixtures/imports/sales_logs" }
let(:sales_log_filename) { "shared_ownership_sales_log" }
let(:sales_log_file) { File.open("#{fixture_directory}/#{sales_log_filename}.xml") }
let(:sales_log_xml) { Nokogiri::XML(sales_log_file) }
let(:organisation) { create(:organisation, old_visible_id: "1", old_org_id: "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618") }
let(:old_user_id) { "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa" }
let(:remote_folder) { "sales_logs" }
before do
create(:user, old_user_id:, organisation:)
allow(storage_service)
.to receive(:list_files)
.and_return(["#{sales_log_filename}.xml"])
allow(storage_service)
.to receive(:get_file_io)
.with("#{sales_log_filename}.xml")
.and_return(sales_log_file)
Timecop.freeze(Time.zone.local(2023, 11, 10))
Singleton.__init__(FormHandler)
end
after do
Timecop.return
end
around do |example|
Timecop.freeze(Time.zone.local(2023, 1, 17)) do
Singleton.__init__(FormHandler)
example.run
end
end
context "when updating creation method" do
let(:field) { "creation_method" }
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
sales_log_file.rewind
end
context "and the log was manually entered" do
let(:sales_log_filename) { "shared_ownership_sales_log" }
it "logs that bulk upload id does not need setting" do
expect(logger).to receive(:info).with("sales log with old id #{sales_log_filename} entered manually, no need for update")
expect { import_service.update_field(field, remote_folder) }.not_to(change { sales_log.reload.creation_method })
end
end
context "and the log was bulk uploaded and the creation method is already correct" do
let(:sales_log_filename) { "shared_ownership_sales_log2" }
it "logs that bulk upload id does not need setting" do
expect(logger).to receive(:info).with(/sales log \d+ creation method already set to bulk upload, no need for update/)
expect { import_service.update_field(field, remote_folder) }.not_to(change { sales_log.reload.creation_method })
end
end
context "and the log was bulk uploaded and the creation method requires updating" do
let(:sales_log_filename) { "shared_ownership_sales_log2" }
it "logs that bulk upload id does not need setting" do
sales_log.creation_method_single_log!
expect(logger).to receive(:info).with(/sales log \d+ creation method set to bulk upload/)
expect { import_service.update_field(field, remote_folder) }.to change { sales_log.reload.creation_method }.to "bulk upload"
end
end
context "and the log was not previously imported" do
let(:sales_log_filename) { "shared_ownership_sales_log" }
it "logs a warning that the log has not been found in the db" do
sales_log.destroy!
expect(logger).to receive(:warn).with("sales log with old id #{sales_log_filename} not found")
import_service.update_field(field, remote_folder)
end
end
end
context "when updating owning_organisation_id" do
let(:field) { "owning_organisation_id" }
let(:sales_log_filename) { "shared_ownership_sales_log" }
context "when the sales log has no offered value" do
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
sales_log_file.rewind
sales_log.update!(owning_organisation_id: nil)
end
it "updates the sales_log owning_organisation_id value" do
expect(logger).to receive(:info).with("sales log #{sales_log.id}'s owning_organisation_id value has been set to #{organisation.id}")
expect { import_service.send(:update_field, field, remote_folder) }
.to(change { sales_log.reload.owning_organisation_id }.from(nil).to(organisation.id))
end
end
context "when the sales log has a different offered value" do
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
sales_log_file.rewind
sales_log.update!(owning_organisation_id: organisation.id)
end
it "does not update the sales_log owning_organisation_id value" do
expect(logger).to receive(:info).with(/sales log \d+ has a value for owning_organisation_id, skipping update/)
expect { import_service.send(:update_field, field, remote_folder) }
.not_to(change { sales_log.reload.owning_organisation_id })
end
end
end
context "when updating old_form_id" do
let(:field) { "old_form_id" }
let(:sales_log_filename) { "shared_ownership_sales_log" }
context "when the sales log has no offered value" do
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
sales_log_file.rewind
sales_log.update!(old_form_id: nil)
end
it "updates the sales_log old_form_id value" do
expect(logger).to receive(:info).with("sales log #{sales_log.id}'s old_form_id value has been set to 300204")
expect { import_service.send(:update_field, field, remote_folder) }
.to(change { sales_log.reload.old_form_id }.from(nil).to(300_204))
end
end
context "when the sales log has a different offered value" do
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
sales_log_file.rewind
sales_log.update!(old_form_id: 123)
end
it "does not update the sales_log old_form_id value" do
expect(logger).to receive(:info).with(/sales log \d+ has a value for old_form_id, skipping update/)
expect { import_service.send(:update_field, field, remote_folder) }
.not_to(change { sales_log.reload.old_form_id })
end
end
end
context "when updating created_by" do
let(:field) { "created_by" }
let(:sales_log_filename) { "shared_ownership_sales_log" }
let(:sales_log) { SalesLog.find_by(old_id: sales_log_filename) }
let(:old_log_id) { sales_log.id }
before do
Imports::SalesLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
old_log_id
sales_log_file.rewind
sales_log.update!(created_by: sales_log.owning_organisation.users.first, values_updated_at: nil)
end
context "when the sales log has created_by value" do
it "skips the update" do
expect(logger).to receive(:info).with(/sales log \d+ has created_by value, skipping update/)
import_service.send(:update_created_by, sales_log_xml)
old_sales_log = SalesLog.find(old_log_id)
expect(old_sales_log).not_to be_nil
new_sales_log = SalesLog.find_by(old_id: sales_log_filename)
expect(new_sales_log).to eq(old_sales_log)
expect(new_sales_log.values_updated_at).to be_nil
end
end
context "when the sales log has no created_by value" do
before do
sales_log.update!(created_by: nil)
end
it "deletes the existing sales log and creates a new log with correct created_by" do
expect(logger).to receive(:info).with(/sales log \d+ has been deleted/)
expect(logger).to receive(:info).with(/sales log "shared_ownership_sales_log" has been reimported with id \d+/)
import_service.send(:update_created_by, sales_log_xml)
old_sales_log = SalesLog.find_by(id: old_log_id)
expect(old_sales_log).to be_nil
new_sales_log = SalesLog.find_by(old_id: sales_log_filename)
expect(new_sales_log).not_to eq(old_sales_log)
expect(new_sales_log.values_updated_at).not_to be_nil
end
it "deletes the existing sales log and creates a new log with correct unassigned created_by" do
sales_log_xml.at_xpath("//meta:owner-user-id").content = "fake_id"
expect(logger).to receive(:info).with(/sales log \d+ has been deleted/)
expect(logger).to receive(:info).with(/sales log "shared_ownership_sales_log" has been reimported with id \d+/)
expect(logger).to receive(:error).with(/Sales log 'shared_ownership_sales_log' belongs to legacy user with owner-user-id: 'fake_id' which cannot be found. Assigning log to 'Unassigned' user./)
import_service.send(:update_created_by, sales_log_xml)
old_sales_log = SalesLog.find_by(id: old_log_id)
expect(old_sales_log).to be_nil
new_sales_log = SalesLog.find_by(old_id: sales_log_filename)
expect(new_sales_log).not_to eq(old_sales_log)
expect(new_sales_log.created_by.name).to eq("Unassigned")
expect(new_sales_log.values_updated_at).not_to be_nil
end
end
context "and the log was not previously imported" do
it "logs a warning that the log has not been found in the db" do
sales_log.destroy!
expect(logger).to receive(:warn).with("sales log with old id #{sales_log_filename} not found")
expect { import_service.send(:update_created_by, sales_log_xml) }.not_to change(SalesLog, :count)
end
end
end
end

2327
spec/services/imports/sales_logs_import_service_spec.rb

File diff suppressed because it is too large Load Diff

74
spec/services/imports/scheme_import_service_spec.rb

@ -1,74 +0,0 @@
require "rails_helper"
RSpec.describe Imports::SchemeImportService do
subject(:scheme_service) { described_class.new(storage_service, logger) }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:fixture_directory) { "spec/fixtures/imports/mgmtgroups" }
let(:scheme_id) { "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d" }
let!(:owning_org) { FactoryBot.create(:organisation, old_org_id: "7c5bd5fb549c09z2c55d9cb90d7ba84927e64618") }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end
context "when importing schemes" do
let(:remote_folder) { "mgmtgroups" }
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{scheme_id}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{scheme_id}.xml")
.and_return(open_file(fixture_directory, scheme_id))
end
it "successfully create all schemes" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn)
expect(logger).not_to receive(:info)
expect { scheme_service.create_schemes(remote_folder) }
.to change(Scheme, :count).by(1)
end
end
context "when importing a specific scheme" do
let(:scheme_file) { open_file(fixture_directory, scheme_id) }
let(:scheme_xml) { Nokogiri::XML(scheme_file) }
it "matches expected values" do
scheme = scheme_service.create_scheme(scheme_xml)
expect(scheme.owning_organisation).to eq(owning_org)
expect(scheme.old_id).to eq("6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d")
expect(scheme.old_visible_id).to eq("0123")
expect(scheme.service_name).to eq("Management Group")
expect(scheme.arrangement_type).to eq("Another organisation")
end
context "and the scheme status is not approved" do
before { scheme_xml.at_xpath("//mgmtgroup:status").content = "Temporary" }
it "does not create the scheme" do
expect(logger).to receive(:warn).with("Scheme with legacy ID 6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d is not approved (Temporary), skipping")
expect { scheme_service.create_scheme(scheme_xml) }
.not_to change(Scheme, :count)
end
end
context "and the scheme arrange type is direct" do
before do
scheme_xml.at_xpath("//mgmtgroup:arrangement_type").content = "D"
scheme_xml.at_xpath("//mgmtgroup:agent").content = ""
end
it "assigns owning organisation" do
scheme = scheme_service.create_scheme(scheme_xml)
expect(scheme.owning_organisation).to eq(owning_org)
end
end
end
end

251
spec/services/imports/scheme_location_import_service_spec.rb

@ -1,251 +0,0 @@
require "rails_helper"
RSpec.describe Imports::SchemeLocationImportService do
subject(:location_service) { described_class.new(storage_service, logger) }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:fixture_directory) { "spec/fixtures/imports/schemes" }
let(:first_location_id) { "0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e" }
let(:second_location_id) { "0bb3836b70b4dd9903263d5a764a5c45b964a89d" }
let!(:scheme) { FactoryBot.create(:scheme, service_name: "Management Group", old_id: "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d", confirmed: nil) }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/S446EJ/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {})
end
context "when importing scheme locations" do
let(:remote_folder) { "schemes" }
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{first_location_id}.xml #{remote_folder}/#{second_location_id}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{first_location_id}.xml")
.and_return(open_file(fixture_directory, first_location_id))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{second_location_id}.xml")
.and_return(open_file(fixture_directory, second_location_id))
end
it "successfully create all scheme locations" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn)
expect(logger).not_to receive(:info)
expect { location_service.create_scheme_locations(remote_folder) }
.to change(Location, :count).by(2)
.and(change(Scheme, :count).by(0))
end
it "successfully sets the scheme to confirmed" do
expect { location_service.create_scheme_locations(remote_folder) }
.to change { scheme.reload.confirmed }.from(nil).to(true)
end
end
context "when importing different scheme locations" do
let(:location_xml_1) { Nokogiri::XML(open_file(fixture_directory, first_location_id)) }
let(:location_xml_2) { Nokogiri::XML(open_file(fixture_directory, second_location_id)) }
before { location_service.create_scheme_location(location_xml_1) }
context "and the scheme type is different" do
before { location_xml_2.at_xpath("//scheme:scheme-type").content = "5" }
it "renames the location scheme name" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Housing for older people")
expect(new_scheme.service_name).to eq("Management Group - Direct Access Hostel")
end
end
context "and the registered under care act is different" do
before { location_xml_2.at_xpath("//scheme:reg-home-type").content = "2" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group")
expect(new_scheme.service_name).to eq("Management Group - (Part-registered care home)")
end
end
context "and the support type is different" do
before { location_xml_2.at_xpath("//scheme:support-type").content = "3" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Low level")
expect(new_scheme.service_name).to eq("Management Group - Medium level")
end
end
context "and the intended stay is different" do
before { location_xml_2.at_xpath("//scheme:intended-stay").content = "S" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Permanent")
expect(new_scheme.service_name).to eq("Management Group - Short stay")
end
end
context "and the primary client group is different" do
before { location_xml_2.at_xpath("//scheme:client-group-1").content = "F" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Older people with support needs")
expect(new_scheme.service_name).to eq("Management Group - People with drug problems")
end
end
context "and the secondary client group is different" do
before { location_xml_2.at_xpath("//scheme:client-group-2").content = "S" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group")
expect(new_scheme.service_name).to eq("Management Group - Rough sleepers")
end
end
end
context "when importing a specific scheme location" do
let(:location_xml) { Nokogiri::XML(open_file(fixture_directory, first_location_id)) }
it "matches expected location values" do
location = location_service.create_scheme_location(location_xml)
expect(location.name).to eq("Location 1")
expect(location.postcode).to eq("S44 6EJ")
expect(location.location_code).to eq("E08000035")
expect(location.units).to eq(5)
expect(location.mobility_type).to eq("Fitted with equipment and adaptations")
expect(location.type_of_unit).to eq("Bungalow")
expect(location.old_id).to eq(first_location_id)
expect(location.old_visible_id).to eq("10")
expect(location.startdate).to eq("1900-01-01")
expect(location.scheme).to eq(scheme)
expect(location.confirmed).to eq(true)
end
it "matches expected schemes values" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.scheme_type).to eq("Housing for older people")
expect(location.scheme.registered_under_care_act).to eq("No")
expect(location.scheme.support_type).to eq("Low level")
expect(location.scheme.intended_stay).to eq("Permanent")
expect(location.scheme.primary_client_group).to eq("Older people with support needs")
expect(location.scheme.secondary_client_group).to be_nil
expect(location.scheme.has_other_client_group).to eq("No")
expect(location.scheme.sensitive).to eq("No")
expect(location.scheme.confirmed).to be_truthy
end
it "creates a deactivation period" do
location = location_service.create_scheme_location(location_xml)
expect(location.location_deactivation_periods.count).to eq(1)
expect(location.location_deactivation_periods.first.deactivation_date).to eq(Time.zone.local(2050, 12, 31))
end
context "and we import the same location twice" do
before { location_service.create_scheme_location(location_xml) }
it "does not create the location" do
expect(logger).to receive(:warn).with("Location is already present with legacy ID 0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e, skipping")
expect { location_service.create_scheme_location(location_xml) }
.not_to change(Location, :count)
end
end
context "and the registered under care act value is zero" do
before { location_xml.at_xpath("//scheme:reg-home-type").content = "0" }
it "sets the registered under care act to nil" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.registered_under_care_act).to be_nil
end
it "sets the confirmed status to false" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.confirmed).to be_falsey
end
end
context "and the registered under care act value is missing" do
before { location_xml.at_xpath("//scheme:reg-home-type").content = "" }
it "sets the registered under care act to nil" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.registered_under_care_act).to be_nil
end
it "sets the confirmed status to false" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.confirmed).to be_falsey
end
end
context "and support_type is not a valid one" do
before { location_xml.at_xpath("//scheme:support-type").content = "1" }
it "sets the support type to missing" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.support_type).to eq("Missing")
end
end
context "and support_type is not answered" do
before { location_xml.at_xpath("//scheme:support-type").content = "" }
it "sets the support type to nil" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.support_type).to eq(nil)
end
end
context "and support_type is floating support" do
before { location_xml.at_xpath("//scheme:support-type").content = "6" }
it "correctly sets the support type" do
location = location_service.create_scheme_location(location_xml)
expect(location.scheme.support_type).to eq("Floating support")
end
end
context "and postcode does not return a location code" do
before { location_xml.at_xpath("//scheme:postcode").content = "A1 1AA" }
it "imports location code correctly" do
location = location_service.create_scheme_location(location_xml)
expect(location.postcode).to eq("A1 1AA")
expect(location.location_code).to eq("E07000033")
end
end
end
end

264
spec/services/imports/user_import_service_spec.rb

@ -1,264 +0,0 @@
require "rails_helper"
RSpec.describe Imports::UserImportService do
let(:fixture_directory) { "spec/fixtures/imports" }
let(:old_user_id) { "fc7625a02b24ae16162aa63ae7cb33feeec0c373" }
let(:old_org_id) { "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618" }
let(:user_file) { File.open("#{fixture_directory}/user/#{old_user_id}.xml") }
let(:storage_service) { instance_double(Storage::S3Service) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:notify_client) { instance_double(Notifications::Client) }
let(:devise_notify_mailer) { DeviseNotifyMailer.new }
before do
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
allow(notify_client).to receive(:send_email).and_return(true)
end
context "when importing users" do
subject(:import_service) { described_class.new(storage_service, logger) }
before do
allow(storage_service).to receive(:list_files)
.with("user_directory")
.and_return(["user_directory/#{old_user_id}.xml"])
allow(storage_service).to receive(:get_file_io)
.with("user_directory/#{old_user_id}.xml")
.and_return(user_file)
allow(logger).to receive(:info)
end
it "successfully create a user with the expected data" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.name).to eq("John Doe")
expect(user.email).to eq("john.doe@gov.uk")
expect(user.encrypted_password).not_to be_nil
expect(user.phone).to eq("02012345678")
expect(user).to be_data_provider
expect(user.organisation.old_org_id).to eq(old_org_id)
expect(user.is_key_contact?).to be false
expect(user.active).to be true
end
it "refuses to create a user belonging to a non existing organisation" do
expect(logger).to receive(:error).with(/Could not save user with email: john.doe@gov.uk/)
expect(logger).to receive(:error).with(/Validation failed: Organisation Select the user’s organisation/)
import_service.create_users("user_directory")
end
context "when the user with the same email already exists" do
before do
create(:organisation, old_org_id:)
create(:user, email: "john.doe@gov.uk")
end
it "logs an error and user email" do
expect(logger).to receive(:error).with(/Could not save user with email: john.doe@gov.uk/)
expect(logger).to receive(:error).with(/Validation failed: email Enter an email address that hasn’t already been used to sign up/)
import_service.create_users("user_directory")
end
end
context "when the user is a data coordinator" do
let(:old_user_id) { "d4729b1a5dfb68bb1e01c08445830c0add40907c" }
it "sets their role correctly" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user).to be_data_coordinator
end
end
context "when the user is a data protection officer" do
let(:old_user_id) { "10c887710550844e2551b3e0fb88dc9b4a8a642b" }
it "marks them as a data protection officer" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.is_data_protection_officer?).to be true
end
end
context "when the user was a 'Key Performance Contact' in the old system" do
let(:old_user_id) { "d4729b1a5dfb68bb1e01c08445830c0add40907c" }
it "marks them as a key contact" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.is_key_contact?).to be true
end
end
context "when the user was a 'eCORE Contact' in the old system" do
let(:old_user_id) { "d6717836154cd9a58f9e2f1d3077e3ab81e07613" }
it "marks them as a key contact" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.is_key_contact?).to be true
end
end
context "when the user has already been imported previously" do
before do
org = FactoryBot.create(:organisation, old_org_id:)
FactoryBot.create(:user, old_user_id:, organisation: org)
end
it "logs that the user already exists" do
expect(logger).to receive(:warn)
import_service.create_users("user_directory")
end
end
context "when the user does not have namespace bindings" do
let(:old_user_id) { "80d9b73aa1c88b6e5c36ee49be9050b923b4a1bb" }
it "imports them succesfully" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.name).to eq("Jane Doe")
expect(user.email).to eq("jane.doe@gov.uk")
end
end
context "when a user has already been imported with that email" do
let!(:org) { FactoryBot.create(:organisation, old_org_id:) }
let!(:user) { FactoryBot.create(:user, :data_provider, organisation: org, email: "john.doe@gov.uk") }
context "when the duplicate role is higher than the original role" do
let(:old_user_id) { "d4729b1a5dfb68bb1e01c08445830c0add40907c" }
it "upgrades their role" do
import_service.create_users("user_directory")
expect(user.reload).to be_data_coordinator
end
it "does not create a new user record" do
expect { import_service.create_users("user_directory") }
.not_to change(User, :count)
end
it "creates a new legacy user record" do
expect { import_service.create_users("user_directory") }.to change(LegacyUser, :count)
end
it "associates the legacy user with the existing user" do
import_service.create_users("user_directory")
expect(LegacyUser.find_by(old_user_id:)&.user).to eq(user)
end
end
context "when the duplicate role is lower than the original role" do
let!(:user) { FactoryBot.create(:user, :data_coordinator, organisation: org, email: "john.doe@gov.uk") }
let(:old_user_id) { "fc7625a02b24ae16162aa63ae7cb33feeec0c373" }
it "does not change their role" do
expect { import_service.create_users("user_directory") }
.not_to(change { user.reload.role })
end
it "does not create a new record" do
expect { import_service.create_users("user_directory") }
.not_to change(User, :count)
end
end
context "when the duplicate record is a data protection officer role" do
let!(:user) { FactoryBot.create(:user, :data_coordinator, organisation: org, email: "john.doe@gov.uk") }
let(:old_user_id) { "10c887710550844e2551b3e0fb88dc9b4a8a642b" }
it "marks them as a data protection officer" do
import_service.create_users("user_directory")
expect(user.reload.is_data_protection_officer?).to be true
end
it "does not create a new record" do
expect { import_service.create_users("user_directory") }
.not_to change(User, :count)
end
end
context "when the user was deactivated in the old system" do
let(:old_user_id) { "9ed81a262215a1634f0809effa683e38924d8bcb" }
it "marks them as not active" do
import_service.create_users("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.active).to be false
end
end
end
context "when only creating specific dsa signers" do
let(:old_dataprotect_id) { "7c5bd5fb549c09a2c55d7cb90d7ba84927e64618" }
let(:dataprotect_file) { File.open("#{fixture_directory}/dataprotect/#{old_dataprotect_id}.xml") }
before do
allow(storage_service).to receive(:list_files)
.with("dataprotect")
.and_return(["dataprotect_directory/#{old_dataprotect_id}.xml"])
allow(storage_service).to receive(:get_file_io)
.with("dataprotect_directory/#{old_dataprotect_id}.xml")
.and_return(dataprotect_file)
allow(logger).to receive(:info)
end
context "when the user is to be imported" do
let(:old_user_id) { "10c887710550844e2551b3e0fb88dc9b4a8a642b" }
it "creates a user with the correct details" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users_who_signed_dpcs("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user.name).to eq("John Doe")
expect(user.email).to eq("john.doe@gov.uk")
expect(user.encrypted_password).not_to be_nil
expect(user.phone).to eq("02012345678")
expect(user.is_data_protection_officer?).to be true
expect(user.organisation.old_org_id).to eq(old_org_id)
expect(user.is_key_contact?).to be false
expect(user.active).to be true
end
end
context "when the user has a different name to the dsa signer" do
let(:old_user_id) { "80d9b73aa1c88b6e5c36ee49be9050b923b4a1bb" }
it "does not create a user" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users_who_signed_dpcs("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user).to be_nil
end
end
context "when the user has the name of the dsa signer but is not a dpo" do
let(:old_user_id) { "9ed81a262215a1634f0809effa683e38924d8bcb" }
it "does not create a user" do
FactoryBot.create(:organisation, old_org_id:)
import_service.create_users_who_signed_dpcs("user_directory")
user = LegacyUser.find_by(old_user_id:)&.user
expect(user).to be_nil
end
end
end
end
end

8
spec/support/bulk_upload/lettings_log_to_csv.rb

@ -238,18 +238,18 @@ private
def london_affordable_rent
case log.renttype
when Imports::LettingsLogsImportService::RENT_TYPE[:london_affordable_rent]
when LettingsLog::RENT_TYPE[:london_affordable_rent]
1
end
end
def intermediate_rent_type
case log.renttype
when Imports::LettingsLogsImportService::RENT_TYPE[:rent_to_buy]
when LettingsLog::RENT_TYPE[:rent_to_buy]
1
when Imports::LettingsLogsImportService::RENT_TYPE[:london_living_rent]
when LettingsLog::RENT_TYPE[:london_living_rent]
2
when Imports::LettingsLogsImportService::RENT_TYPE[:other_intermediate_rent_product]
when LettingsLog::RENT_TYPE[:other_intermediate_rent_product]
3
end
end

Loading…
Cancel
Save