Browse Source

CLDC-2291 refactor and minor updates to lettings log csv service (#1719)

* form handler to return all questions from lettings forms for all years with ordering interleaved
functionality and tests

* refactor lettings log csv service and all associated tests
remove methods on log models when we can call them directly on associated models
update job to call the service directly with the collection of logs rather
minor modifications to the sales log csv service
update many test files to test the appropriate logic in the appropriate place

* tidying
final amendments to tests
remove commented code
rename variable

* change the position of the rent value check field in the headers

* CLDC-2492 add creation method field to logs (#1738)

* create migrations to add creation method fields to both log types

* add enum definition to logs for creation method

* upadte csv export services to retrieve creation method values direct from the log, remove methods previously used from the log model

* run migrations to update schema

* ensure that logs created via bulk upload have this set correctly when created
CLDC-2492-create-rake-task-to-set-creation-method-for-existing-logs
Arthur Campbell 2 years ago committed by GitHub
parent
commit
8c34719987
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/jobs/email_csv_job.rb
  2. 12
      app/models/form_handler.rb
  3. 17
      app/models/lettings_log.rb
  4. 10
      app/models/log.rb
  5. 1
      app/services/bulk_upload/lettings/log_creator.rb
  6. 1
      app/services/bulk_upload/sales/log_creator.rb
  7. 184
      app/services/csv/lettings_log_csv_service.rb
  8. 46
      app/services/csv/sales_log_csv_service.rb
  9. 5
      db/migrate/20230629124739_add_creation_method_to_lettings_logs.rb
  10. 5
      db/migrate/20230629125541_add_creation_method_to_sales_logs.rb
  11. 6
      db/schema.rb
  12. 2
      spec/fixtures/files/lettings_log_csv_export_codes.csv
  13. 2
      spec/fixtures/files/lettings_log_csv_export_labels.csv
  14. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv
  15. 2
      spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv
  16. 2
      spec/fixtures/files/lettings_logs_download.csv
  17. 2
      spec/fixtures/files/lettings_logs_download_codes_only.csv
  18. 2
      spec/fixtures/files/lettings_logs_download_non_support.csv
  19. 4
      spec/fixtures/files/sales_logs_csv_export_codes.csv
  20. 4
      spec/fixtures/files/sales_logs_csv_export_labels.csv
  21. 177
      spec/jobs/email_csv_job_spec.rb
  22. 51
      spec/models/form_handler_spec.rb
  23. 109
      spec/models/lettings_log_spec.rb
  24. 6
      spec/services/bulk_upload/lettings/log_creator_spec.rb
  25. 8
      spec/services/bulk_upload/sales/log_creator_spec.rb
  26. 623
      spec/services/csv/lettings_log_csv_service_spec.rb
  27. 27
      spec/services/csv/sales_log_csv_service_spec.rb

4
app/jobs/email_csv_job.rb

@ -6,15 +6,15 @@ class EmailCsvJob < ApplicationJob
EXPIRATION_TIME = 3.hours.to_i
def perform(user, search_term = nil, filters = {}, all_orgs = false, organisation = nil, codes_only_export = false, log_type = "lettings") # rubocop:disable Style/OptionalBooleanParameter - sidekiq can't serialise named params
export_type = codes_only_export ? "codes" : "labels"
case log_type
when "lettings"
unfiltered_logs = organisation.present? && user.support? ? LettingsLog.visible.where(owning_organisation_id: organisation.id) : user.lettings_logs.visible
filtered_logs = FilterManager.filter_logs(unfiltered_logs, search_term, filters, all_orgs, user)
csv_string = filtered_logs.to_csv(user, codes_only_export:)
csv_string = Csv::LettingsLogCsvService.new(user:, export_type:).prepare_csv(filtered_logs)
when "sales"
unfiltered_logs = organisation.present? && user.support? ? SalesLog.visible.where(owning_organisation_id: organisation.id) : user.sales_logs.visible
filtered_logs = FilterManager.filter_logs(unfiltered_logs, search_term, filters, all_orgs, user)
export_type = codes_only_export ? "codes" : "labels"
csv_string = Csv::SalesLogCsvService.new(export_type:).prepare_csv(filtered_logs)
end

12
app/models/form_handler.rb

@ -52,6 +52,18 @@ class FormHandler
ordered_questions
end
def ordered_lettings_questions_for_all_years
lettings_forms = forms.filter { |name, _form| name.end_with? "lettings" }.values
ordered_questions = lettings_forms.pop.questions.uniq(&:id)
question_ids = ordered_questions.map(&:id)
all_questions_from_previous_forms = lettings_forms.flat_map(&:questions)
deprecated_questions_by_preceding_question_id(question_ids, all_questions_from_previous_forms).each do |preceding_question_id, deprecated_question|
index_of_preceding_question = ordered_questions.index { |q| q.id == preceding_question_id }
ordered_questions.insert(index_of_preceding_question + 1, deprecated_question)
end
ordered_questions
end
def deprecated_questions_by_preceding_question_id(current_form_question_ids, all_questions_from_previous_forms)
deprecated_questions = {}
all_questions_from_previous_forms.each_cons(2) do |preceding_question, question|

17
app/models/lettings_log.rb

@ -411,23 +411,6 @@ class LettingsLog < Log
managing_organisation&.name
end
def created_by_name
created_by&.name
end
def is_dpo
created_by&.is_dpo
end
def scheme_code
scheme&.id ? "S#{scheme.id}" : nil
end
def self.to_csv(user = nil, codes_only_export:)
export_type = codes_only_export ? "codes" : "labels"
Csv::LettingsLogCsvService.new(user, export_type:).to_csv
end
def beds_for_la_rent_range
return 0 if is_supported_housing?

10
app/models/log.rb

@ -20,6 +20,12 @@ class Log < ApplicationRecord
enum status: STATUS
enum status_cache: STATUS, _prefix: true
CREATION_METHOD = {
"single log" => 1,
"bulk upload" => 2,
}.freeze
enum creation_method: CREATION_METHOD
scope :visible, -> { where(status: %w[not_started in_progress completed]) }
scope :exportable, -> { where(status: %w[not_started in_progress completed deleted]) }
@ -178,10 +184,6 @@ class Log < ApplicationRecord
end
end
def creation_method
bulk_uploaded? ? "bulk upload" : "single log"
end
def bulk_uploaded?
bulk_upload_id.present?
end

1
app/services/bulk_upload/lettings/log_creator.rb

@ -14,6 +14,7 @@ class BulkUpload::Lettings::LogCreator
row_parser.log.blank_invalid_non_setup_fields!
row_parser.log.bulk_upload = bulk_upload
row_parser.log.creation_method = "bulk upload"
row_parser.log.skip_update_status = true
row_parser.log.status = "pending"
row_parser.log.status_cache = row_parser.log.calculate_status

1
app/services/bulk_upload/sales/log_creator.rb

@ -14,6 +14,7 @@ class BulkUpload::Sales::LogCreator
row_parser.log.blank_invalid_non_setup_fields!
row_parser.log.bulk_upload = bulk_upload
row_parser.log.creation_method = "bulk upload"
row_parser.log.skip_update_status = true
row_parser.log.status = "pending"
row_parser.log.status_cache = row_parser.log.calculate_status

184
app/services/csv/lettings_log_csv_service.rb

@ -1,26 +1,32 @@
module Csv
class LettingsLogCsvService
CSV_FIELDS_TO_OMIT = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc unresolved updated_by_id bulk_upload_id uprn_confirmed status_cache discarded_at].freeze
def initialize(user, export_type:)
def initialize(user:, export_type:)
@user = user
@export_type = export_type
set_csv_attributes
@attributes = lettings_log_attributes
end
def to_csv
def prepare_csv(logs)
CSV.generate(headers: true) do |csv|
csv << @attributes
LettingsLog.all.find_each do |record|
csv << @attributes.map { |attribute| get_value(attribute, record) }
logs.find_each do |log|
csv << @attributes.map { |attribute| value(attribute, log) }
end
end
end
private
ATTRIBUTES_OF_RELATED_OBJECTS = {
CUSTOM_CALL_CHAINS = {
created_by: {
labels: %i[created_by email],
codes: %i[created_by email],
},
updated_by: {
labels: %i[updated_by email],
codes: %i[updated_by email],
},
location_code: {
labels: %i[location id],
codes: %i[location id],
@ -61,7 +67,7 @@ module Csv
labels: %i[scheme sensitive],
codes: %i[scheme sensitive_before_type_cast],
},
scheme_type: {
SCHTYPE: {
labels: %i[scheme scheme_type],
codes: %i[scheme scheme_type_before_type_cast],
},
@ -97,36 +103,66 @@ module Csv
labels: %i[scheme created_at],
codes: %i[scheme created_at],
},
scheme_code: {
labels: %i[scheme id_to_display],
codes: %i[scheme id_to_display],
},
creation_method: {
labels: %i[creation_method],
codes: %i[creation_method_before_type_cast],
},
is_dpo: {
labels: %i[created_by is_dpo?],
codes: %i[created_by is_dpo?],
},
}.freeze
def get_value(attribute, record)
attribute = "rent_type" if attribute == "rent_type_detail" # rent_type_detail is the requested column header for rent_type, so as not to confuse with renttype
if ATTRIBUTES_OF_RELATED_OBJECTS.key? attribute.to_sym
call_chain = ATTRIBUTES_OF_RELATED_OBJECTS[attribute.to_sym][@export_type.to_sym]
call_chain.reduce(record) { |object, next_call| object&.send(next_call) }
elsif %w[la prevloc].include? attribute # for all exports we output both the codes and labels for these location attributes
record.send(attribute)
elsif %w[la_label prevloc_label].include? attribute # as above
attribute = attribute.remove("_label")
field_value = record.send(attribute)
get_label(field_value, attribute, record)
elsif %w[mrcdate startdate voiddate].include? attribute
record.send(attribute)&.to_formatted_s(:govuk_date)
FIELDS_ALWAYS_EXPORTED_AS_CODES = %w[
la
prevloc
].freeze
FIELDS_ALWAYS_EXPORTED_AS_LABELS = {
"la_label" => "la",
"prevloc_label" => "prevloc",
}.freeze
DATE_FIELDS = %w[
mrcdate
startdate
voiddate
created_at
updated_at
].freeze
def value(attribute, log)
attribute = "rent_type" if attribute == "rent_type_detail" # rent_type_detail is the requested column header for rent_type, so as not to confuse with renttype. It can be exported as label or code.
if CUSTOM_CALL_CHAINS.key? attribute.to_sym
call_chain = CUSTOM_CALL_CHAINS[attribute.to_sym][@export_type.to_sym]
call_chain.reduce(log) { |object, next_call| object&.public_send(next_call) }
elsif FIELDS_ALWAYS_EXPORTED_AS_CODES.include? attribute
log.public_send(attribute)
elsif FIELDS_ALWAYS_EXPORTED_AS_LABELS.key? attribute
attribute = FIELDS_ALWAYS_EXPORTED_AS_LABELS[attribute]
value = log.public_send(attribute)
get_label(value, attribute, log)
elsif DATE_FIELDS.include? attribute
log.public_send(attribute)&.iso8601
else
field_value = record.send(attribute)
value = log.public_send(attribute)
case @export_type
when "codes"
field_value
value
when "labels"
answer_label = get_label(field_value, attribute, record)
answer_label || label_if_boolean_value(field_value) || field_value
answer_label = get_label(value, attribute, log)
answer_label || label_if_boolean_value(value) || value
end
end
end
def get_label(value, attribute, record)
record.form
.get_question(attribute, record)
def get_label(value, attribute, log)
log.form
.get_question(attribute, log)
&.label_from_value(value)
end
@ -135,60 +171,52 @@ module Csv
return "No" if value == false
end
def set_csv_attributes
metadata_fields = %w[id status created_at updated_at created_by_name is_dpo owning_organisation_name managing_organisation_name collection_start_year]
metadata_id_fields = %w[managing_organisation_id owning_organisation_id created_by_id bulk_upload_id]
scheme_and_location_ids = %w[scheme_id location_id]
scheme_attributes = %w[scheme_code scheme_service_name scheme_sensitive scheme_type scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at]
location_attributes = %w[location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate]
intersecting_attributes = ordered_form_questions & LettingsLog.attribute_names - scheme_and_location_ids
remaining_attributes = LettingsLog.attribute_names - intersecting_attributes - scheme_and_location_ids
@attributes = (metadata_fields + intersecting_attributes + remaining_attributes - metadata_id_fields + %w[unittype_sh] + scheme_attributes + location_attributes).uniq
move_la_fields
rename_attributes
@attributes -= CSV_FIELDS_TO_OMIT if @user.present? && !@user.support?
end
ATTRIBUTE_MAPPINGS = {
"owning_organisation_id" => %w[owning_organisation_name],
"managing_organisation_id" => %w[managing_organisation_name],
"created_by_id" => [],
"scheme_id" => [],
"location_id" => [],
"rent_type" => %w[renttype rent_type_detail],
"hb" => %w[hb has_benefits],
"age1" => %w[refused hhtype totchild totelder totadult age1],
"housingneeds_type" => %w[housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h],
"net_income_known" => %w[net_income_known incref],
"irproduct_other" => %w[irproduct irproduct_other lar],
"la" => %w[is_la_inferred la_label la],
"prevloc" => %w[is_previous_la_inferred prevloc_label prevloc],
"needstype" => %w[needstype lettype],
"prevten" => %w[prevten new_old],
"voiddate" => %w[voiddate vacdays],
"rsnvac" => %w[rsnvac newprop],
"household_charge" => %w[household_charge nocharge],
"brent" => %w[brent wrent rent_value_check],
"scharge" => %w[scharge wscharge],
"pscharge" => %w[pscharge wpschrge],
"supcharg" => %w[supcharg wsupchrg],
"tcharge" => %w[tcharge wtcharge],
"chcharge" => %w[chcharge wchchrg],
"tshortfall" => %w[tshortfall wtshortfall],
}.freeze
def ordered_form_questions
downloaded_form_years = LettingsLog.all.map(&:collection_start_year).uniq.compact
SUPPORT_ONLY_ATTRIBUTES = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc updated_by_id bulk_upload_id uprn_confirmed].freeze
if downloaded_form_years.count == 1 && downloaded_form_years[0].present?
form_name = FormHandler.instance.form_name_from_start_year(downloaded_form_years[0], "lettings")
downloaded_form_fields = FormHandler.instance.get_form(form_name).questions
def lettings_log_attributes
ordered_questions = FormHandler.instance.ordered_lettings_questions_for_all_years
ordered_questions.reject! { |q| q.id.match?(/rent_value_check/) }
attributes = ordered_questions.flat_map do |question|
if question.type == "checkbox"
question.answer_options.keys.reject { |key| key == "divider" }
elsif ATTRIBUTE_MAPPINGS.key? question.id
ATTRIBUTE_MAPPINGS[question.id]
else
downloaded_form_fields = FormHandler.instance.current_lettings_form.questions
end
move_checkbox_answer_options(downloaded_form_fields)
end
def move_checkbox_answer_options(form_questions)
checkboxes = form_questions.filter { |question| question.type == "checkbox" }.map { |question| { "#{question.id}": question.answer_options.keys } }
attributes = form_questions.map(&:id).uniq
checkboxes.each do |checkbox_question|
checkbox_question.values[0].each do |answer_option|
attributes.insert(attributes.find_index(checkbox_question.keys[0].to_s), answer_option)
end
question.id
end
attributes
end
def move_la_fields
{ la: %w[is_la_inferred la_label], prevloc: %w[is_previous_la_inferred prevloc_label] }.each do |inferred_field, fields|
fields.each do |field|
@attributes.delete(field)
@attributes.insert(@attributes.find_index(inferred_field.to_s), field)
end
end
end
def rename_attributes
{ "rent_type" => "rent_type_detail" }.each do |original_field, new_field|
@attributes.insert(@attributes.find_index(original_field), new_field)
@attributes.delete(original_field)
end
non_question_fields = %w[id status created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year]
scheme_and_location_attributes = %w[scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate]
final_attributes = non_question_fields + attributes + scheme_and_location_attributes
@user.support? ? final_attributes : final_attributes - SUPPORT_ONLY_ATTRIBUTES
end
end
end

46
app/services/csv/sales_log_csv_service.rb

@ -17,13 +17,35 @@ module Csv
private
ATTRIBUTES_OF_RELATED_OBJECTS = {
day: %i[saledate day],
month: %i[saledate month],
year: %i[saledate year],
is_dpo: %i[created_by is_dpo],
created_by_name: %i[created_by name],
owning_organisation_name: %i[owning_organisation name],
CUSTOM_CALL_CHAINS = {
day: {
labels: %i[saledate day],
codes: %i[saledate day],
},
month: {
labels: %i[saledate month],
codes: %i[saledate month],
},
year: {
labels: %i[saledate year],
codes: %i[saledate year],
},
is_dpo: {
labels: %i[created_by is_dpo],
codes: %i[created_by is_dpo],
},
created_by: {
labels: %i[created_by email],
codes: %i[created_by email],
},
owning_organisation_name: {
labels: %i[owning_organisation name],
codes: %i[owning_organisation name],
},
creation_method: {
labels: %i[creation_method],
codes: %i[creation_method_before_type_cast],
},
}.freeze
FIELDS_ALWAYS_EXPORTED_AS_CODES = %w[
@ -42,15 +64,15 @@ module Csv
].freeze
def value(attribute, log)
if ATTRIBUTES_OF_RELATED_OBJECTS.key? attribute.to_sym
call_chain = ATTRIBUTES_OF_RELATED_OBJECTS[attribute.to_sym]
if CUSTOM_CALL_CHAINS.key? attribute.to_sym
call_chain = CUSTOM_CALL_CHAINS[attribute.to_sym][@export_type.to_sym]
call_chain.reduce(log) { |object, next_call| object&.public_send(next_call) }
elsif FIELDS_ALWAYS_EXPORTED_AS_CODES.include? attribute
log.send(attribute)
elsif FIELDS_ALWAYS_EXPORTED_AS_LABELS.key? attribute
attribute = FIELDS_ALWAYS_EXPORTED_AS_LABELS[attribute]
field_value = log.send(attribute)
get_label(field_value, attribute, log)
value = log.send(attribute)
get_label(value, attribute, log)
elsif DATE_FIELDS.include? attribute
log.send(attribute)&.iso8601
else
@ -84,7 +106,7 @@ module Csv
"ppostcode_full" => %w[ppostc1 ppostc2],
"la" => %w[la la_label],
"prevloc" => %w[prevloc prevloc_label],
"created_by_id" => %w[created_by_name],
"created_by_id" => %w[created_by],
"owning_organisation_id" => %w[owning_organisation_name],
}.freeze

5
db/migrate/20230629124739_add_creation_method_to_lettings_logs.rb

@ -0,0 +1,5 @@
class AddCreationMethodToLettingsLogs < ActiveRecord::Migration[7.0]
def change
add_column :lettings_logs, :creation_method, :integer, default: 1
end
end

5
db/migrate/20230629125541_add_creation_method_to_sales_logs.rb

@ -0,0 +1,5 @@
class AddCreationMethodToSalesLogs < ActiveRecord::Migration[7.0]
def change
add_column :sales_logs, :creation_method, :integer, default: 1
end
end

6
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_06_21_142422) do
ActiveRecord::Schema[7.0].define(version: 2023_06_29_125541) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -290,6 +290,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_06_21_142422) do
t.integer "carehome_charges_value_check"
t.integer "status_cache", default: 0, null: false
t.datetime "discarded_at"
t.integer "creation_method", default: 1
t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
t.index ["location_id"], name: "index_lettings_logs_on_location_id"
@ -600,11 +601,12 @@ ActiveRecord::Schema[7.0].define(version: 2023_06_21_142422) do
t.integer "discounted_sale_value_check"
t.integer "student_not_child_value_check"
t.integer "percentage_discount_value_check"
t.integer "combined_income_value_check"
t.integer "buyer_livein_value_check"
t.integer "status_cache", default: 0, null: false
t.integer "combined_income_value_check"
t.datetime "discarded_at"
t.integer "stairowned_value_check"
t.integer "creation_method", default: 1
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true

2
spec/fixtures/files/lettings_log_csv_export_codes.csv vendored

@ -0,0 +1,2 @@
id,status,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,rent_type_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,age1_known,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,ecstat1,details_known_2,relat2,age2_known,age2,sex2,ecstat2,details_known_3,relat3,age3_known,age3,sex3,ecstat3,details_known_4,relat4,age4_known,age4,sex4,ecstat4,details_known_5,relat5,age5_known,age5,sex5,ecstat5,details_known_6,relat6,age6_known,age6,sex6,ecstat6,details_known_7,relat7,age7_known,age7,sex7,ecstat7,details_known_8,relat8,age8_known,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_unknown,referral,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
,completed,s.port@jeemayle.com,false,2023-06-26T00:00:00+01:00,,2023-06-26T00:00:00+01:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-06-26T00:00:00+01:00,2,1,,,,HIJKLMN,ABCDEFG,0,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-06-24T00:00:00+01:00,,,1,2023-06-25T00:00:00+01:00,,3,1,4,,2,,1,2,,0,0,4,0,0,2,35,,F,0,2,13,0,0,P,0,32,M,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,2,1,1,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,,2,0,0,68,1,,6,1,1,,0,2,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,1,0,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype rent_type_detail irproduct irproduct_other lar tenancycode propcode uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb pregnancy_value_check age1_known refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national ecstat1 details_known_2 relat2 age2_known age2 sex2 ecstat2 details_known_3 relat3 age3_known age3 sex3 ecstat3 details_known_4 relat4 age4_known age4 sex4 ecstat4 details_known_5 relat5 age5_known age5 sex5 ecstat5 details_known_6 relat6 age6_known age6 sex6 ecstat6 details_known_7 relat7 age7_known age7 sex7 ecstat7 details_known_8 relat8 age8_known age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_unknown referral net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 completed s.port@jeemayle.com false 2023-06-26T00:00:00+01:00 2023-06-26T00:00:00+01:00 1 2023 DLUHC DLUHC 1 7 0 2023-06-26T00:00:00+01:00 2 1 HIJKLMN ABCDEFG 0 fake address London NW9 5LL false Barnet E09000003 0 2 6 2 2 7 1 1 3 2023-06-24T00:00:00+01:00 1 2023-06-25T00:00:00+01:00 3 1 4 2 1 2 0 0 4 0 0 2 35 F 0 2 13 0 0 P 0 32 M 6 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 2 1 1 TN23 6LZ 1 false Ashford E07000105 1 0 1 0 0 0 0 0 1 2 0 0 68 1 6 1 1 0 2 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 1 0 12.0 6.0

2
spec/fixtures/files/lettings_log_csv_export_labels.csv vendored

@ -0,0 +1,2 @@
id,status,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,rent_type_detail,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,hhmemb,pregnancy_value_check,age1_known,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,ecstat1,details_known_2,relat2,age2_known,age2,sex2,ecstat2,details_known_3,relat3,age3_known,age3,sex3,ecstat3,details_known_4,relat4,age4_known,age4,sex4,ecstat4,details_known_5,relat5,age5_known,age5,sex5,ecstat5,details_known_6,relat6,age6_known,age6,sex6,ecstat6,details_known_7,relat7,age7_known,age7,sex7,ecstat7,details_known_8,relat8,age8_known,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,letting_allocation_unknown,referral,net_income_known,incref,earnings,incfreq,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
,completed,s.port@jeemayle.com,false,2023-06-26T00:00:00+01:00,,2023-06-26T00:00:00+01:00,single log,,,2023,DLUHC,DLUHC,General needs,7,No,2023-06-26T00:00:00+01:00,2,Affordable Rent,,,,HIJKLMN,ABCDEFG,No,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,2,2,House,Purpose built,Yes,3,2023-06-24T00:00:00+01:00,,,Yes,2023-06-25T00:00:00+01:00,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,1,2,,Yes,0,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,Other,Yes,Partner,Yes,32,Male,Not seeking work,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,1,0,0,0,0,0,No,Yes,0,0,1,0,0,0,0,0,0,0,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,0,1,0,0,0,0,0,1,,Tenant applied directly (no referral or nomination),Yes,0,68,Weekly,,Universal Credit housing element,1,All,,0,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype rent_type_detail irproduct irproduct_other lar tenancycode propcode uprn_known uprn uprn_confirmed address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration hhmemb pregnancy_value_check age1_known refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national ecstat1 details_known_2 relat2 age2_known age2 sex2 ecstat2 details_known_3 relat3 age3_known age3 sex3 ecstat3 details_known_4 relat4 age4_known age4 sex4 ecstat4 details_known_5 relat5 age5_known age5 sex5 ecstat5 details_known_6 relat6 age6_known age6 sex6 ecstat6 details_known_7 relat7 age7_known age7 sex7 ecstat7 details_known_8 relat8 age8_known age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr letting_allocation_unknown referral net_income_known incref earnings incfreq net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 completed s.port@jeemayle.com false 2023-06-26T00:00:00+01:00 2023-06-26T00:00:00+01:00 single log 2023 DLUHC DLUHC General needs 7 No 2023-06-26T00:00:00+01:00 2 Affordable Rent HIJKLMN ABCDEFG No fake address London NW9 5LL No Barnet E09000003 No Affordable rent basis Tenant abandoned property 2 2 House Purpose built Yes 3 2023-06-24T00:00:00+01:00 Yes 2023-06-25T00:00:00+01:00 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 1 2 Yes 0 4 0 0 2 35 Female White Irish Tenant prefers not to say Other Yes Partner Yes 32 Male Not seeking work Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing 1 0 0 0 0 0 No Yes 0 0 1 0 0 0 0 0 0 0 Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing 2 No Yes TN23 6LZ Yes No Ashford E07000105 Yes 0 1 0 0 0 0 0 1 Tenant applied directly (no referral or nomination) Yes 0 68 Weekly Universal Credit housing element 1 All 0 Every 2 weeks 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 Yes Yes 12.0 6.0

2
spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv vendored

@ -0,0 +1,2 @@
id,status,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,lettype,renewal,startdate,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,refused,age1,sex1,ethnic_group,ethnic,national,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,referral,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
,completed,choreographer@owtluk.com,false,2023-06-26T00:00:00+01:00,,2023-06-26T00:00:00+01:00,1,2023,DLUHC,DLUHC,7,0,2023-06-26T00:00:00+01:00,,,,HIJKLMN,ABCDEFG,0,,fake address,,London,,NW9 5LL,Barnet,2,6,2,2,7,1,1,3,2023-06-24T00:00:00+01:00,,1,2023-06-25T00:00:00+01:00,,3,1,4,,2,,1,0,35,F,0,2,13,0,P,32,M,6,,,,,,,,,,,,,,,,,,,,,,,,,1,4,1,2,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,2,7,4,,6,1,1,TN23 6LZ,Ashford,1,0,1,0,0,0,0,0,1,2,0,68,1,6,1,1,,0,2,,,,200.0,50.0,40.0,35.0,325.0,1,12.0,,,,,,,,,,,,,,,,,,,,
1 id status created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name lettype renewal startdate irproduct irproduct_other lar tenancycode propcode uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration refused age1 sex1 ethnic_group ethnic national ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr referral incref earnings incfreq hb has_benefits benefits household_charge nocharge period chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 completed choreographer@owtluk.com false 2023-06-26T00:00:00+01:00 2023-06-26T00:00:00+01:00 1 2023 DLUHC DLUHC 7 0 2023-06-26T00:00:00+01:00 HIJKLMN ABCDEFG 0 fake address London NW9 5LL Barnet 2 6 2 2 7 1 1 3 2023-06-24T00:00:00+01:00 1 2023-06-25T00:00:00+01:00 3 1 4 2 1 0 35 F 0 2 13 0 P 32 M 6 1 4 1 2 1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 2 7 4 6 1 1 TN23 6LZ Ashford 1 0 1 0 0 0 0 0 1 2 0 68 1 6 1 1 0 2 200.0 50.0 40.0 35.0 325.0 1 12.0

2
spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv vendored

@ -0,0 +1,2 @@
id,status,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,collection_start_year,owning_organisation_name,managing_organisation_name,lettype,renewal,startdate,irproduct,irproduct_other,lar,tenancycode,propcode,uprn_known,uprn,address_line1,address_line2,town_or_city,county,postcode_full,la_label,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,declaration,refused,age1,sex1,ethnic_group,ethnic,national,ecstat1,relat2,age2,sex2,ecstat2,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,relat7,age7,sex7,ecstat7,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,prevten,homeless,ppcodenk,ppostcode_full,prevloc_label,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,referral,incref,earnings,incfreq,hb,has_benefits,benefits,household_charge,nocharge,period,chcharge,wchchrg,carehome_charges_value_check,brent,scharge,pscharge,supcharg,tcharge,hbrentshortfall,tshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_admin_district,location_startdate
,completed,choreographer@owtluk.com,false,2023-06-26T00:00:00+01:00,,2023-06-26T00:00:00+01:00,single log,2023,DLUHC,DLUHC,7,No,2023-06-26T00:00:00+01:00,,,,HIJKLMN,ABCDEFG,No,,fake address,,London,,NW9 5LL,Barnet,Affordable rent basis,Tenant abandoned property,2,2,House,Purpose built,Yes,3,2023-06-24T00:00:00+01:00,,Yes,2023-06-25T00:00:00+01:00,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,1,0,35,Female,White,Irish,Tenant prefers not to say,Other,Partner,32,Male,Not seeking work,,,,,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,1,0,0,0,0,0,No,Yes,0,0,1,0,0,0,0,0,0,0,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,Other supported housing,No,Yes,TN23 6LZ,Ashford,Yes,0,1,0,0,0,0,0,1,Tenant applied directly (no referral or nomination),0,68,Weekly,Universal Credit housing element,1,All,,0,Every 2 weeks,,,,200.0,50.0,40.0,35.0,325.0,Yes,12.0,,,,,,,,,,,,,,,,,,,,
1 id status created_by is_dpo created_at updated_by updated_at creation_method collection_start_year owning_organisation_name managing_organisation_name lettype renewal startdate irproduct irproduct_other lar tenancycode propcode uprn_known uprn address_line1 address_line2 town_or_city county postcode_full la_label unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered declaration refused age1 sex1 ethnic_group ethnic national ecstat1 relat2 age2 sex2 ecstat2 relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 relat7 age7 sex7 ecstat7 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother prevten homeless ppcodenk ppostcode_full prevloc_label reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr referral incref earnings incfreq hb has_benefits benefits household_charge nocharge period chcharge wchchrg carehome_charges_value_check brent scharge pscharge supcharg tcharge hbrentshortfall tshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_admin_district location_startdate
2 completed choreographer@owtluk.com false 2023-06-26T00:00:00+01:00 2023-06-26T00:00:00+01:00 single log 2023 DLUHC DLUHC 7 No 2023-06-26T00:00:00+01:00 HIJKLMN ABCDEFG No fake address London NW9 5LL Barnet Affordable rent basis Tenant abandoned property 2 2 House Purpose built Yes 3 2023-06-24T00:00:00+01:00 Yes 2023-06-25T00:00:00+01:00 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 1 0 35 Female White Irish Tenant prefers not to say Other Partner 32 Male Not seeking work Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing 1 0 0 0 0 0 No Yes 0 0 1 0 0 0 0 0 0 0 Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing No Yes TN23 6LZ Ashford Yes 0 1 0 0 0 0 0 1 Tenant applied directly (no referral or nomination) 0 68 Weekly Universal Credit housing element 1 All 0 Every 2 weeks 200.0 50.0 40.0 35.0 325.0 Yes 12.0

2
spec/fixtures/files/lettings_logs_download.csv vendored

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

2
spec/fixtures/files/lettings_logs_download_codes_only.csv vendored

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

2
spec/fixtures/files/lettings_logs_download_non_support.csv vendored

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

4
spec/fixtures/files/sales_logs_csv_export_codes.csv vendored

@ -1,2 +1,2 @@
id,status,created_at,updated_at,old_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,created_by_name,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,2023-02-08T00:00:00+00:00,2023-02-08T00:00:00+00:00,,2022,single log,false,DLUHC,Danny Rojas,8,2,2023,,2,8,,,,1,1,2,1,1,0,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,1,2,1,30,X,17,17,18,1,1,P,35,X,17,,13,1,1,6,C,14,X,9,X,18,X,3,R,40,X,2,R,40,X,1,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,10000.0
id,status,created_at,updated_at,old_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,2023-02-08T00:00:00+00:00,2023-02-08T00:00:00+00:00,,2022,1,false,DLUHC,billyboy@eyeklaud.com,8,2,2023,,2,8,,,,1,1,2,1,1,0,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,1,2,1,30,X,17,17,18,1,1,P,35,X,17,,13,1,1,6,C,14,X,9,X,18,X,3,R,40,X,2,R,40,X,1,1,1,,,0,,,1,1,1,1,,3,,1,4,5,1,1,0,10000,1,0,10000,1,4,1,,1,2,10,,,,,,,,,,,,,,,,,110000.0,,1,20000.0,5,,10,1,80000.0,,,1,100.0,,10000.0

1 id status created_at updated_at old_id collection_start_year creation_method is_dpo owning_organisation_name created_by_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore beds proptype builtype pcodenk uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label wchair noint privacynotice age1 sex1 ethnic_group ethnic national ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-02-08T00:00:00+00:00 2023-02-08T00:00:00+00:00 2022 single log 1 false DLUHC Danny Rojas billyboy@eyeklaud.com 8 2 2023 2 8 1 1 2 1 1 0 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 1 2 1 30 X 17 17 18 1 1 P 35 X 17 13 1 1 6 C 14 X 9 X 18 X 3 R 40 X 2 R 40 X 1 1 1 0 1 1 1 1 3 1 4 5 1 1 0 10000 1 0 10000 1 4 1 1 2 10 110000.0 1 20000.0 5 10 1 80000.0 1 100.0 10000.0

4
spec/fixtures/files/sales_logs_csv_export_labels.csv vendored

@ -1,2 +1,2 @@
id,status,created_at,updated_at,old_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,created_by_name,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,2023-02-08T00:00:00+00:00,2023-02-08T00:00:00+00:00,,2022,single log,false,DLUHC,Danny Rojas,8,2,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,Yes,,,Address line 1,,Town or city,,SW1A,1AA,Yes,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer 1 prefers not to say,17,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,17,,13,Full-time - 30 hours or more,Yes,6,Child,14,Non-binary,Child under 16,Other,18,Non-binary,"In government training into work, such as New Deal",Person prefers not to say,40,Non-binary,Part-time - Less than 30 hours,Person prefers not to say,40,Non-binary,Full-time - 30 hours or more,Local authority tenant,No,,,No,,,1,1,1,1,,3,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,Don’t know ,No,,Yes,2,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0
id,status,created_at,updated_at,old_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,2023-02-08T00:00:00+00:00,2023-02-08T00:00:00+00:00,,2022,single log,false,DLUHC,billyboy@eyeklaud.com,8,2,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,Yes,,,Address line 1,,Town or city,,SW1A,1AA,Yes,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer 1 prefers not to say,17,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,17,,13,Full-time - 30 hours or more,Yes,6,Child,14,Non-binary,Child under 16,Other,18,Non-binary,"In government training into work, such as New Deal",Person prefers not to say,40,Non-binary,Part-time - Less than 30 hours,Person prefers not to say,40,Non-binary,Full-time - 30 hours or more,Local authority tenant,No,,,No,,,1,1,1,1,,3,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,2,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0

1 id status created_at updated_at old_id collection_start_year creation_method is_dpo owning_organisation_name created_by_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore beds proptype builtype pcodenk uprn uprn_confirmed address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label wchair noint privacynotice age1 sex1 ethnic_group ethnic national ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-02-08T00:00:00+00:00 2023-02-08T00:00:00+00:00 2022 single log false DLUHC Danny Rojas billyboy@eyeklaud.com 8 2 2023 Yes - a discounted ownership scheme Right to Acquire (RTA) Yes Yes 2 Flat or maisonette Purpose built Yes Address line 1 Town or city SW1A 1AA Yes E09000003 Barnet Yes Yes 1 30 Non-binary Buyer 1 prefers not to say 17 United Kingdom Full-time - 30 hours or more Yes Partner 35 Non-binary 17 13 Full-time - 30 hours or more Yes 6 Child 14 Non-binary Child under 16 Other 18 Non-binary In government training into work, such as New Deal Person prefers not to say 40 Non-binary Part-time - Less than 30 hours Person prefers not to say 40 Non-binary Full-time - 30 hours or more Local authority tenant No No 1 1 1 1 3 Yes Yes No Yes Yes Yes 10000 Yes Yes 10000 Yes Don’t know No Yes 2 10 110000.0 Yes 20000.0 Cambridge Building Society 10 Yes 80000.0 Yes 100.0 10000.0

177
spec/jobs/email_csv_job_spec.rb

@ -7,35 +7,19 @@ describe EmailCsvJob do
let(:job) { described_class.new }
let(:user) { FactoryBot.create(:user) }
let(:organisation) { user.organisation }
let(:other_organisation) { FactoryBot.create(:organisation) }
let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") }
before do
allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form)
end
context "when a log exists" do
let!(:lettings_log) do
FactoryBot.create(
:lettings_log,
created_by: user,
ecstat1: 1,
)
end
let(:storage_service) { instance_double(Storage::S3Service) }
let(:mailer) { instance_double(CsvDownloadMailer) }
let(:sales_log_csv_service) { instance_double(Csv::SalesLogCsvService) }
let(:lettings_log_csv_service) { instance_double(Csv::LettingsLogCsvService) }
let(:search_term) { "meaning" }
let(:filters) { { "user" => "yours", "status" => %w[in_progress] } }
let(:all_orgs) { false }
let(:organisation) { build(:organisation) }
let(:codes_only_export) { true }
let(:lettings_logs) { build_list(:lettings_log, 5) }
let(:sales_logs) { build_list(:sales_log, 5) }
before do
FactoryBot.create(:lettings_log,
:completed,
created_by: user,
startdate: Time.zone.local(2022, 5, 1),
voiddate: Time.zone.local(2022, 5, 1),
mrcdate: Time.zone.local(2022, 5, 1))
allow(Storage::S3Service).to receive(:new).and_return(storage_service)
allow(storage_service).to receive(:write_file)
allow(storage_service).to receive(:get_presigned_url).and_return(test_url)
@ -43,11 +27,18 @@ describe EmailCsvJob do
allow(Csv::SalesLogCsvService).to receive(:new).and_return(sales_log_csv_service)
allow(sales_log_csv_service).to receive(:prepare_csv).and_return("")
allow(Csv::LettingsLogCsvService).to receive(:new).and_return(lettings_log_csv_service)
allow(lettings_log_csv_service).to receive(:prepare_csv).and_return("")
allow(CsvDownloadMailer).to receive(:new).and_return(mailer)
allow(mailer).to receive(:send_csv_download_mail)
end
context "when exporting lettings logs" do
before do
allow(FilterManager).to receive(:filter_logs).and_return(lettings_logs)
end
it "uses an appropriate filename in S3" do
expect(storage_service).to receive(:write_file).with(/lettings-logs-.*\.csv/, anything)
job.perform(user)
@ -57,9 +48,32 @@ describe EmailCsvJob do
expect(storage_service).to receive(:write_file).with(/lettings-logs-#{organisation.name}-.*\.csv/, anything)
job.perform(user, nil, {}, nil, organisation)
end
it "calls the filter manager with the arguments provided" do
expect(FilterManager).to receive(:filter_logs).with(a_kind_of(ActiveRecord::Relation), search_term, filters, all_orgs, user)
job.perform(user, search_term, filters, all_orgs, organisation, codes_only_export)
end
it "creates a LettingsLogCsvService with the correct export type" do
expect(Csv::LettingsLogCsvService).to receive(:new).with(user:, export_type: "labels")
codes_only = false
job.perform(user, nil, {}, nil, nil, codes_only, "lettings")
expect(Csv::LettingsLogCsvService).to receive(:new).with(user:, export_type: "codes")
codes_only = true
job.perform(user, nil, {}, nil, nil, codes_only, "lettings")
end
it "passes the logs returned by the filter manager to the csv service" do
expect(lettings_log_csv_service).to receive(:prepare_csv).with(lettings_logs)
job.perform(user, nil, {}, nil, nil, codes_only_export)
end
end
context "when exporting sales logs" do
before do
allow(FilterManager).to receive(:filter_logs).and_return(sales_logs)
end
it "uses an appropriate filename in S3" do
expect(storage_service).to receive(:write_file).with(/sales-logs-.*\.csv/, anything)
job.perform(user, nil, {}, nil, nil, nil, "sales")
@ -70,6 +84,11 @@ describe EmailCsvJob do
job.perform(user, nil, {}, nil, organisation, nil, "sales")
end
it "calls the filter manager with the arguments provided" do
expect(FilterManager).to receive(:filter_logs).with(a_kind_of(ActiveRecord::Relation), search_term, filters, all_orgs, user)
job.perform(user, search_term, filters, all_orgs, organisation, codes_only_export, "sales")
end
it "creates a SalesLogCsvService with the correct export type" do
expect(Csv::SalesLogCsvService).to receive(:new).with(export_type: "labels")
codes_only = false
@ -78,115 +97,15 @@ describe EmailCsvJob do
codes_only = true
job.perform(user, nil, {}, nil, nil, codes_only, "sales")
end
end
it "sends an E-mail with the presigned URL and duration" do
expect(mailer).to receive(:send_csv_download_mail).with(user, test_url, instance_of(Integer))
job.perform(user)
end
context "when writing to S3" do
before do
FactoryBot.create_list(:lettings_log, 4, owning_organisation: other_organisation)
FactoryBot.create(:lettings_log, owning_organisation: other_organisation, status: "pending", skip_update_status: true)
end
def expect_csv
expect(storage_service).to receive(:write_file) do |_filename, data|
# Ignore byte order marker
csv = CSV.parse(data[1..])
yield(csv)
end
end
it "writes CSV data with headers" do
expect_csv do |csv|
expect(csv.first.first).to eq("id")
expect(csv.second.first).to eq(lettings_log.id.to_s)
end
job.perform(user)
end
context "when there is no organisation provided" do
it "only writes logs from the user's organisation" do
expect_csv do |csv|
# Headings + 2 rows
expect(csv.count).to eq(3)
it "passes the logs returned by the filter manager to the csv service" do
expect(sales_log_csv_service).to receive(:prepare_csv).with(sales_logs)
job.perform(user, nil, {}, nil, nil, codes_only_export, "sales")
end
job.perform(user)
end
end
context "when the user is support and an organisation is provided" do
let(:user) { FactoryBot.create(:user, :support) }
it "only writes logs from that organisation" do
expect_csv do |csv|
# other organisation => Headings + 4 rows
expect(csv.count).to eq(5)
end
job.perform(user, nil, {}, nil, other_organisation)
end
end
it "writes answer labels rather than values" do
expect_csv do |csv|
expect(csv.second[19]).to eq("Full-time – 30 hours or more")
end
job.perform(user)
end
it "writes filtered logs" do
expect_csv do |csv|
expect(csv.count).to eq(2)
end
job.perform(user, nil, { status: "completed" })
end
it "writes searched logs" do
expect_csv do |csv|
expect(csv.count).to eq(LettingsLog.search_by(lettings_log.id.to_s).count + 1)
end
job.perform(user, lettings_log.id.to_s)
end
context "when both filter and search applied" do
let(:postcode) { "XX1 1TG" }
before do
FactoryBot.create(:lettings_log, :in_progress, postcode_full: postcode, owning_organisation: organisation, created_by: user)
FactoryBot.create(:lettings_log, :completed, postcode_full: postcode, owning_organisation: organisation, created_by: user)
end
it "downloads logs matching both csv and filter logs" do
expect_csv do |csv|
expect(csv.count).to eq(2)
end
job.perform(user, postcode, { status: "completed" })
end
end
context "when there are more than 20 logs" do
before do
FactoryBot.create_list(:lettings_log, 26, owning_organisation: organisation)
end
it "does not paginate, it downloads all the user's logs" do
expect_csv do |csv|
# Heading + 2 + 26
expect(csv.count).to eq(29)
end
it "sends an E-mail with the presigned URL and duration" do
expect(mailer).to receive(:send_csv_download_mail).with(user, test_url, instance_of(Integer))
job.perform(user)
end
end
end
end
end

51
spec/models/form_handler_spec.rb

@ -270,5 +270,56 @@ RSpec.describe FormHandler do
expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3]
end
end
describe "#ordered_lettings_questions_for_all_years" do
let(:result) { described_class.instance.ordered_lettings_questions_for_all_years }
let(:now) { Time.zone.now }
it "returns an array of questions" do
section = build(:section, :with_questions, question_ids: %w[1 2 3])
lettings_form = FormFactory.new(year: 2936, type: "lettings")
.with_sections([section])
.build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form })
expect(result).to(satisfy { |result| result.all? { |element| element.is_a?(Form::Question) } })
end
it "does not return multiple questions with the same id" do
first_section = build(:section, :with_questions, question_ids: %w[1 2 3])
second_section = build(:section, :with_questions, question_ids: %w[2 3 4 5])
lettings_form = FormFactory.new(year: 2936, type: "lettings")
.with_sections([first_section, second_section])
.build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5]
end
it "returns the questions in the same order as the form" do
first_section = build(:section, :with_questions, question_ids: %w[1 2 3])
second_section = build(:section, :with_questions, question_ids: %w[4 5 6])
lettings_form = FormFactory.new(year: 2945, type: "lettings")
.with_sections([first_section, second_section])
.build
described_class.instance.use_fake_forms!({ only_lettings: lettings_form })
expect(result.map(&:id)).to eq %w[1 2 3 4 5 6]
end
it "inserts questions from all years in their correct positions" do
original_section = build(:section, :with_questions, question_ids: %w[1 1a_deprecated 2 3])
new_section = build(:section, :with_questions, question_ids: %w[1 2 2a_new 3])
original_form = FormFactory.new(year: 2066, type: "lettings")
.with_sections([original_section])
.build
new_form = FormFactory.new(year: 2485, type: "lettings")
.with_sections([new_section])
.build
fake_forms = {
earlier_lettings: original_form,
newer_lettings: new_form,
}
described_class.instance.use_fake_forms!(fake_forms)
expect(result.map(&:id)).to eq %w[1 1a_deprecated 2 2a_new 3]
end
end
# rubocop:enable RSpec/PredicateMatcher
end

109
spec/models/lettings_log_spec.rb

@ -2857,115 +2857,6 @@ RSpec.describe LettingsLog do
end
end
describe "csv download" do
let(:scheme) { create(:scheme) }
let(:location) do
create(
:location,
:export,
scheme:,
type_of_unit: 6,
postcode: "SE11TE",
startdate: Time.zone.local(2021, 10, 1),
)
end
let(:user) { create(:user, organisation: location.scheme.owning_organisation) }
let(:expected_content) { csv_export_file.read }
after do
Timecop.unfreeze
end
context "with values represented as human readable labels" do
before do
Timecop.freeze(Time.utc(2022, 6, 5))
lettings_log = FactoryBot.create(
:lettings_log,
needstype: 2,
scheme:,
location:,
owning_organisation: scheme.owning_organisation,
created_by: user,
rent_type: 2,
startdate: Time.zone.local(2021, 10, 2),
created_at: Time.zone.local(2022, 2, 8, 16, 52, 15),
updated_at: Time.zone.local(2022, 2, 8, 16, 52, 15),
)
expected_content.sub!(/\{id\}/, lettings_log["id"].to_s)
expected_content.sub!(/\{scheme_code\}/, "S#{scheme['id']}")
expected_content.sub!(/\{scheme_service_name\}/, scheme["service_name"].to_s)
expected_content.sub!(/\{scheme_sensitive\}/, scheme["sensitive"].to_s)
expected_content.sub!(/\{scheme_primary_client_group\}/, scheme["primary_client_group"].to_s)
expected_content.sub!(/\{scheme_secondary_client_group\}/, scheme["secondary_client_group"].to_s)
expected_content.sub!(/\{scheme_support_type\}/, scheme["support_type"].to_s)
expected_content.sub!(/\{scheme_intended_stay\}/, scheme["intended_stay"].to_s)
expected_content.sub!(/\{location_code\}/, location["id"].to_s)
expected_content.sub!(/\{location_startdate\}/, location["startdate"].to_s)
expected_content.sub!(/\{scheme_id\}/, scheme["service_name"].to_s)
expected_content.sub!(/\{location_id\}/, location["id"].to_s)
end
around do |example|
Timecop.freeze(Time.zone.local(2022, 6, 5)) do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
context "with a support user" do
let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download.csv", "r:UTF-8") }
it "generates a correct csv from a lettings log" do
expect(described_class.to_csv(codes_only_export: false)).to eq(expected_content)
end
end
context "with a non support user" do
let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download_non_support.csv", "r:UTF-8") }
it "generates a correct csv from a lettings log" do
expect(described_class.to_csv(user, codes_only_export: false)).to eq(expected_content)
end
end
end
context "with values represented as codes" do
before do
Timecop.freeze(Time.utc(2022, 6, 5))
lettings_log = FactoryBot.create(:lettings_log, needstype: 2, scheme:, location:, owning_organisation: scheme.owning_organisation, created_by: user, rent_type: 2, startdate: Time.zone.local(2021, 10, 2), created_at: Time.zone.local(2022, 2, 8, 16, 52, 15), updated_at: Time.zone.local(2022, 2, 8, 16, 52, 15))
expected_content.sub!(/\{id\}/, lettings_log["id"].to_s)
expected_content.sub!(/\{scheme_code\}/, "S#{scheme.id}")
expected_content.sub!(/\{scheme_service_name\}/, scheme.service_name.to_s)
expected_content.sub!(/\{scheme_sensitive\}/, scheme.sensitive_before_type_cast.to_s)
expected_content.sub!(/\{scheme_primary_client_group\}/, scheme.primary_client_group_before_type_cast.to_s)
expected_content.sub!(/\{scheme_secondary_client_group\}/, scheme.secondary_client_group_before_type_cast.to_s)
expected_content.sub!(/\{scheme_support_type\}/, scheme.support_type_before_type_cast.to_s)
expected_content.sub!(/\{scheme_intended_stay\}/, scheme.intended_stay_before_type_cast.to_s)
expected_content.sub!(/\{location_code\}/, location.id.to_s)
expected_content.sub!(/\{location_startdate\}/, location.startdate.to_s)
expected_content.sub!(/\{scheme_id\}/, scheme.service_name.to_s)
expected_content.sub!(/\{location_id\}/, location.id.to_s)
end
let(:csv_export_file) { File.open("spec/fixtures/files/lettings_logs_download_codes_only.csv", "r:UTF-8") }
around do |example|
Timecop.freeze(Time.zone.local(2022, 6, 5)) do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
it "generates a correct csv from a lettings log" do
expect(described_class.to_csv(codes_only_export: true)).to eq(expected_content)
end
end
end
describe "#blank_invalid_non_setup_fields!" do
context "when a setup field is invalid" do
subject(:model) { described_class.new(needstype: 404) }

6
spec/services/bulk_upload/lettings/log_creator_spec.rb

@ -27,6 +27,12 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
expect(log.bulk_upload).to eql(bulk_upload)
expect(bulk_upload.lettings_logs).to include(log)
end
it "sets the creation method" do
service.call
expect(LettingsLog.last.creation_method).to eq "bulk upload"
end
end
context "when a valid csv with several blank rows" do

8
spec/services/bulk_upload/sales/log_creator_spec.rb

@ -15,8 +15,6 @@ RSpec.describe BulkUpload::Sales::LogCreator do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
context "when a valid csv with new log" do
@ -36,6 +34,12 @@ RSpec.describe BulkUpload::Sales::LogCreator do
expect(log.bulk_upload).to eql(bulk_upload)
expect(bulk_upload.sales_logs).to include(log)
end
it "sets the creation method" do
service.call
expect(SalesLog.last.creation_method).to eq "bulk upload"
end
end
context "when a valid csv with several blank rows" do

623
spec/services/csv/lettings_log_csv_service_spec.rb

@ -1,430 +1,227 @@
require "rails_helper"
RSpec.describe Csv::LettingsLogCsvService do
context "when the user is support" do
let(:user) { create(:user, :support) }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") }
let(:form_handler_mock) { instance_double(FormHandler) }
let(:organisation) { create(:organisation) }
let(:fixed_time) { Time.zone.local(2023, 6, 26) }
let(:log) do
create(
:lettings_log,
:completed,
startdate: fixed_time,
created_at: fixed_time,
updated_at: fixed_time,
mrcdate: fixed_time - 1.day,
voiddate: fixed_time - 2.days,
propcode: "ABCDEFG",
tenancycode: "HIJKLMN",
postcode_full: "NW9 5LL",
ppostcode_full: "TN23 6LZ",
created_by: user,
managing_organisation: organisation,
)
end
let(:user) { create(:user, :support, email: "s.port@jeemayle.com") }
let(:service) { described_class.new(user:, export_type:) }
let(:export_type) { "labels" }
let(:csv) { CSV.parse(service.prepare_csv(LettingsLog.where(id: logs.map(&:id)))) }
let(:logs) { [log] }
let(:headers) { csv.first }
it "calls the form handler to get all questions in order when initialized" do
allow(FormHandler).to receive(:instance).and_return(form_handler_mock)
allow(form_handler_mock).to receive(:ordered_lettings_questions_for_all_years).and_return([])
service
expect(form_handler_mock).to have_received(:ordered_lettings_questions_for_all_years)
end
it "returns a string" do
result = service.prepare_csv(LettingsLog.all)
expect(result).to be_a String
end
it "returns a csv with headers" do
expect(csv.first.first).to eq "id"
end
context "when stubbing :ordered_lettings_questions_for_all_years" do
let(:lettings_form) do
FormFactory.new(year: 2050, type: "lettings")
.with_sections([build(:section, :with_questions, question_ids:, questions:)])
.build
end
let(:question_ids) { nil }
let(:questions) { nil }
before do
LettingsLog.create!(startdate: Time.zone.today, created_at: Time.utc(2022, 2, 8, 16, 52, 15))
allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form)
end
it "sets csv attributes in correct order" do
expected_csv_attributes = %w[
id
status
created_at
updated_at
created_by_name
is_dpo
owning_organisation_name
managing_organisation_name
collection_start_year
needstype
renewal
startdate
rent_type_detail
irproduct_other
tenancycode
propcode
postcode_known
postcode_full
is_la_inferred
la_label
la
first_time_property_let_as_social_housing
unitletas
rsnvac
offered
unittype_gn
builtype
wchair
beds
voiddate
void_date_value_check
majorrepairs
mrcdate
major_repairs_date_value_check
startertenancy
tenancy
tenancyother
tenancylength
sheltered
declaration
hhmemb
pregnancy_value_check
age1_known
age1
sex1
ethnic_group
ethnic
national
ecstat1
retirement_value_check
details_known_2
relat2
age2_known
age2
sex2
ecstat2
details_known_3
relat3
age3_known
age3
sex3
ecstat3
details_known_4
relat4
age4_known
age4
sex4
ecstat4
details_known_5
relat5
age5_known
age5
sex5
ecstat5
details_known_6
relat6
age6_known
age6
sex6
ecstat6
details_known_7
relat7
age7_known
age7
sex7
ecstat7
details_known_8
relat8
age8_known
age8
sex8
ecstat8
armedforces
leftreg
reservist
preg_occ
housingneeds
housingneeds_type
housingneeds_other
illness
illness_type_4
illness_type_5
illness_type_2
illness_type_6
illness_type_7
illness_type_3
illness_type_9
illness_type_8
illness_type_1
illness_type_10
layear
waityear
reason
reasonother
prevten
underoccupation_benefitcap
homeless
ppcodenk
ppostcode_full
previous_la_known
is_previous_la_inferred
prevloc_label
prevloc
reasonpref
rp_homeless
rp_insan_unsat
rp_medwel
rp_hardship
rp_dontknow
cbl
cap
chr
letting_allocation_unknown
referral
net_income_known
earnings
incfreq
net_income_value_check
hb
benefits
household_charge
period
is_carehome
chcharge
carehome_charges_value_check
brent
scharge
pscharge
supcharg
tcharge
rent_value_check
hbrentshortfall
tshortfall_known
tshortfall
housingneeds_a
housingneeds_b
housingneeds_c
housingneeds_f
housingneeds_g
housingneeds_h
property_owner_organisation
property_manager_organisation
purchaser_code
property_relet
incref
renttype
lettype
totchild
totelder
totadult
nocharge
has_benefits
wrent
wscharge
wpschrge
wsupchrg
wtcharge
wtshortfall
refused
wchchrg
newprop
old_form_id
lar
irproduct
old_id
joint
hhtype
new_old
vacdays
unresolved
updated_by_id
uprn
uprn_known
uprn_confirmed
address_line1
address_line2
town_or_city
county
status_cache
discarded_at
unittype_sh
scheme_code
scheme_service_name
scheme_sensitive
scheme_type
scheme_registered_under_care_act
scheme_owning_organisation_name
scheme_primary_client_group
scheme_has_other_client_group
scheme_secondary_client_group
scheme_support_type
scheme_intended_stay
scheme_created_at
location_code
location_postcode
location_name
location_units
location_type_of_unit
location_mobility_type
location_admin_district
location_startdate
allow(FormHandler).to receive(:instance).and_return(form_handler_mock)
allow(form_handler_mock).to receive(:form_name_from_start_year)
allow(form_handler_mock).to receive(:get_form).and_return(lettings_form)
allow(form_handler_mock).to receive(:ordered_lettings_questions_for_all_years).and_return(lettings_form.questions)
allow(form_handler_mock).to receive(:lettings_in_crossover_period?).and_return false
end
context "when it returns questions with particular ids" do
let(:question_ids) { %w[prevten startdate brent rent_type] }
it "includes log attributes related to questions to the headers" do
expect(headers).to include(*question_ids.first(3))
end
it "removes some log attributes related to questions from the headers and replaces them with their derived values in the correct order" do
expect(headers).not_to include "rent_type"
expect(headers).to include(*%w[wrent renttype rent_type_detail])
end
end
context "when it returns checkbox questions" do
let(:questions) do
[
build(:question, id: "condition_effects", type: "checkbox", answer_options: { "illness_type_1" => {}, "illness_type_2" => {}, "illness_type_3" => {} }),
build(:question, id: "letting_allocation", type: "checkbox", answer_options: { "cbl" => {}, "cap" => {}, "chr" => {} }),
]
end
csv = CSV.parse(described_class.new(user, export_type: "labels").to_csv)
it "does not add the id of the checkbox question to the headers" do
question_ids = questions.map(&:id)
expect(headers).not_to include(*question_ids)
end
expect(csv.first).to eq(expected_csv_attributes)
it "adds the related log attributes from the answer options to the headers" do
log_attributes = questions.flat_map { |q| q.answer_options.keys }
expect(headers).to include(*log_attributes)
end
end
end
context "when the user is not support" do
let(:user) { FactoryBot.create(:user) }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") }
it "adds log attributes not related to questions to the headers" do
expect(headers.first(5)).to eq %w[id status created_by is_dpo created_at]
end
before do
LettingsLog.create!(startdate: Time.zone.today, created_at: Time.utc(2022, 2, 8, 16, 52, 15))
allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form)
end
it "sets csv attributes in correct order and without omitted values" do
expected_csv_attributes = %w[
id
status
created_at
updated_at
created_by_name
is_dpo
owning_organisation_name
managing_organisation_name
collection_start_year
renewal
startdate
irproduct_other
tenancycode
propcode
postcode_full
la_label
unitletas
rsnvac
offered
unittype_gn
builtype
wchair
beds
voiddate
void_date_value_check
majorrepairs
mrcdate
major_repairs_date_value_check
startertenancy
tenancy
tenancyother
tenancylength
sheltered
declaration
age1
sex1
ethnic_group
ethnic
national
ecstat1
relat2
age2
sex2
ecstat2
relat3
age3
sex3
ecstat3
relat4
age4
sex4
ecstat4
relat5
age5
sex5
ecstat5
relat6
age6
sex6
ecstat6
relat7
age7
sex7
ecstat7
relat8
age8
sex8
ecstat8
armedforces
leftreg
reservist
preg_occ
housingneeds
housingneeds_type
housingneeds_other
illness
illness_type_4
illness_type_5
illness_type_2
illness_type_6
illness_type_7
illness_type_3
illness_type_9
illness_type_8
illness_type_1
illness_type_10
layear
waityear
reason
reasonother
prevten
underoccupation_benefitcap
homeless
ppcodenk
ppostcode_full
prevloc_label
reasonpref
rp_homeless
rp_insan_unsat
rp_medwel
rp_hardship
rp_dontknow
cbl
cap
chr
referral
earnings
incfreq
hb
benefits
household_charge
period
chcharge
carehome_charges_value_check
brent
scharge
pscharge
supcharg
tcharge
hbrentshortfall
tshortfall
housingneeds_a
housingneeds_b
housingneeds_c
housingneeds_f
housingneeds_g
housingneeds_h
property_owner_organisation
property_manager_organisation
purchaser_code
property_relet
incref
lettype
nocharge
has_benefits
refused
wchchrg
newprop
lar
irproduct
joint
uprn
uprn_known
address_line1
address_line2
town_or_city
county
unittype_sh
scheme_code
scheme_service_name
scheme_sensitive
scheme_type
scheme_registered_under_care_act
scheme_owning_organisation_name
scheme_primary_client_group
scheme_has_other_client_group
scheme_secondary_client_group
scheme_support_type
scheme_intended_stay
scheme_created_at
location_code
location_postcode
location_name
location_units
location_type_of_unit
location_mobility_type
location_admin_district
location_startdate
]
it "adds attributes related to associated schemes and locations to the headers" do
expect(headers).to include(*%w[scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act])
expect(headers.last(5)).to eq %w[location_units location_type_of_unit location_mobility_type location_admin_district location_startdate]
end
context "when there are many logs" do
let(:logs) { create_list(:lettings_log, log_count) }
let(:log_count) { 30 }
it "creates a CSV with the correct number of logs" do
expected_row_count_with_headers = log_count + 1
expect(csv.size).to be expected_row_count_with_headers
end
end
context "when exporting with human readable labels" do
let(:export_type) { "labels" }
it "gives answer to radio questions as labels" do
relat2_column_index = csv.first.index("relat2")
relat2_value = csv.second[relat2_column_index]
expect(relat2_value).to eq "Partner"
end
it "gives answers to free input questions as the user input" do
age1_column_index = csv.first.index("age1")
age1_value = csv.second[age1_column_index]
expect(age1_value).to eq 35.to_s
end
it "exports the code for the local authority under the heading 'la'" do
la_column_index = csv.first.index("la")
la_value = csv.second[la_column_index]
expect(la_value).to eq "E09000003"
end
it "exports the label for the local authority under the heading 'la_label'" do
la_label_column_index = csv.first.index("la_label")
la_label_value = csv.second[la_label_column_index]
expect(la_label_value).to eq "Barnet"
end
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when exporting as codes" do
let(:export_type) { "codes" }
it "gives answer to radio questions as labels" do
relat2_column_index = csv.first.index("relat2")
relat2_value = csv.second[relat2_column_index]
expect(relat2_value).to eq "P"
end
it "gives answers to free input questions as the user input" do
age1_column_index = csv.first.index("age1")
age1_value = csv.second[age1_column_index]
expect(age1_value).to eq 35.to_s
end
it "exports the code for the local authority under the heading 'la'" do
la_column_index = csv.first.index("la")
la_value = csv.second[la_column_index]
expect(la_value).to eq "E09000003"
end
csv = CSV.parse(described_class.new(user, export_type: "labels").to_csv)
it "exports the label for the local authority under the heading 'la_label'" do
la_label_column_index = csv.first.index("la_label")
la_label_value = csv.second[la_label_column_index]
expect(la_label_value).to eq "Barnet"
end
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "when the user is not a support user" do
let(:user) { create(:user, email: "choreographer@owtluk.com") }
it "does not include certain attributes in the headers" do
expect(headers).not_to include(*%w[rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge])
end
expect(csv.first).to eq(expected_csv_attributes)
context "and exporting with labels" do
let(:export_type) { "labels" }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "and exporting values as codes" do
let(:export_type) { "codes" }
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
end
end

27
spec/services/csv/sales_log_csv_service_spec.rb

@ -3,23 +3,27 @@ require "rails_helper"
RSpec.describe Csv::SalesLogCsvService do
let(:form_handler_mock) { instance_double(FormHandler) }
let(:organisation) { create(:organisation) }
let!(:log) { create(:sales_log, :completed, owning_organisation: organisation, purchid: nil) }
let(:fixed_time) { Time.zone.local(2023, 2, 8) }
let(:user) { create(:user, email: "billyboy@eyeKLAUD.com") }
let!(:log) do
create(
:sales_log,
:completed,
created_by: user,
saledate: fixed_time,
created_at: fixed_time,
updated_at: fixed_time,
owning_organisation: organisation,
purchid: nil,
)
end
let(:service) { described_class.new(export_type: "labels") }
let(:csv) { CSV.parse(service.prepare_csv(SalesLog.all)) }
around do |example|
Timecop.freeze(Time.utc(2023, 2, 8)) do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
it "calls the form handler to get all questions in order when initialized" do
allow(FormHandler).to receive(:instance).and_return(form_handler_mock)
allow(form_handler_mock).to receive(:ordered_sales_questions_for_all_years).and_return([])
described_class.new(export_type: "codes")
service
expect(form_handler_mock).to have_received(:ordered_sales_questions_for_all_years)
end
@ -30,7 +34,6 @@ RSpec.describe Csv::SalesLogCsvService do
it "returns a csv with headers" do
expect(csv.first.first).to eq "id"
expect(csv.second.first).not_to be log.id.to_s
end
context "when stubbing :ordered_sales_questions_for_all_years" do

Loading…
Cancel
Save