From 999a33e0f7dd43e859d370ca2bb1aa7095c8998a Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:43:23 +0000 Subject: [PATCH 1/4] CLDC-3313 Update financial sale validations (#2313) * Rename method * Update staircase/non staircase validations * Add errors to type * Remove validate_shared_ownership_deposit * Don't add setup BU errors, deduplicate different sale type errors * Add tolerance * Reuse method * Rename methods * Skip type error completely in BU * Update validation messages * Update over tolerance method --- .../pages/about_deposit_with_discount.rb | 4 +- .../pages/about_deposit_without_discount.rb | 4 +- app/models/sales_log.rb | 9 +- .../sales/financial_validations.rb | 17 -- .../sales/sale_information_validations.rb | 102 +++++-- .../validations/sales/soft_validations.rb | 10 +- .../bulk_upload/sales/year2024/row_parser.rb | 102 +++++-- config/locales/en.yml | 12 +- .../pages/about_deposit_with_discount_spec.rb | 8 +- .../about_deposit_without_discount_spec.rb | 8 +- .../sales/financial_validations_spec.rb | 175 ------------ .../sale_information_validations_spec.rb | 254 ++++++++++++++++-- .../sales/year2024/row_parser_spec.rb | 26 ++ 13 files changed, 465 insertions(+), 266 deletions(-) diff --git a/app/models/form/sales/pages/about_deposit_with_discount.rb b/app/models/form/sales/pages/about_deposit_with_discount.rb index 5d1e41a95..4f1eed451 100644 --- a/app/models/form/sales/pages/about_deposit_with_discount.rb +++ b/app/models/form/sales/pages/about_deposit_with_discount.rb @@ -14,9 +14,9 @@ class Form::Sales::Pages::AboutDepositWithDiscount < ::Form::Page def depends_on if form.start_year_after_2024? - [{ "is_type_discount?" => true, "stairowned_100?" => @optional }] + [{ "social_homebuy?" => true, "stairowned_100?" => @optional }] else - [{ "is_type_discount?" => true }] + [{ "social_homebuy?" => true }] end end end diff --git a/app/models/form/sales/pages/about_deposit_without_discount.rb b/app/models/form/sales/pages/about_deposit_without_discount.rb index fdd74cf31..5747c3ed4 100644 --- a/app/models/form/sales/pages/about_deposit_without_discount.rb +++ b/app/models/form/sales/pages/about_deposit_without_discount.rb @@ -14,11 +14,11 @@ class Form::Sales::Pages::AboutDepositWithoutDiscount < ::Form::Page def depends_on if form.start_year_after_2024? - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => @optional }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }] else - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }] end diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index f35393a51..5223c249b 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -239,7 +239,7 @@ class SalesLog < Log ownershipsch == 3 || (ownershipsch == 2 && rent_to_buy_full_ownership?) end - def is_type_discount? + def social_homebuy? type == 18 end @@ -287,6 +287,13 @@ class SalesLog < Log mortgage_amount + deposit_amount + cashdis_amount end + def deposit_and_discount_total + deposit_amount = deposit || 0 + cashdis_amount = cashdis || 0 + + deposit_amount + cashdis_amount + end + def value_times_equity return unless value && equity diff --git a/app/models/validations/sales/financial_validations.rb b/app/models/validations/sales/financial_validations.rb index 6b36091ac..3e1d3dfb8 100644 --- a/app/models/validations/sales/financial_validations.rb +++ b/app/models/validations/sales/financial_validations.rb @@ -102,23 +102,6 @@ module Validations::Sales::FinancialValidations end end - def validate_shared_ownership_deposit(record) - return unless record.saledate && record.form.start_year_after_2024? - return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3 - return unless record.cashdis && record.deposit && record.value && record.equity - - mortgage_value = record.mortgage || 0 - - if mortgage_value + record.deposit + record.cashdis != record.value * record.equity / 100 - %i[mortgage value deposit ownershipsch cashdis equity].each do |field| - record.errors.add field, I18n.t("validations.financial.shared_ownership_deposit", - mortgage_deposit_and_discount_error_fields: record.mortgage_deposit_and_discount_error_fields, - mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), - value_times_equity: record.field_formatted_as_currency("value_times_equity")) - end - end - end - def validate_equity_less_than_staircase_difference(record) return unless record.equity && record.stairbought && record.stairowned return unless record.saledate && record.form.start_year_after_2024? diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index 883e10d1d..81054e830 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -107,53 +107,115 @@ module Validations::Sales::SaleInformationValidations end def validate_non_staircasing_mortgage(record) + return unless record.saledate && record.form.start_year_after_2024? return unless record.value && record.deposit && record.equity - return unless record.is_not_staircasing? + return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_not_staircasing? + + if record.social_homebuy? + check_non_staircasing_socialhomebuy_mortgage(record) + else + check_non_staircasing_non_socialhomebuy_mortgage(record) + end + end + + def validate_staircasing_mortgage(record) return unless record.saledate && record.form.start_year_after_2024? + return unless record.value && record.deposit && record.stairbought + return unless record.shared_ownership_scheme? && record.type && record.mortgageused && record.is_staircase? + + if record.social_homebuy? + check_staircasing_socialhomebuy_mortgage(record) + else + check_staircasing_non_socialhomebuy_mortgage(record) + end + end + + def validate_mortgage_used_and_stairbought(record) + return unless record.stairowned && record.mortgageused + + if !record.stairowned_100? && record.mortgageused == 3 + record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + end + end + + def check_non_staircasing_socialhomebuy_mortgage(record) + return unless record.cashdis + + if record.mortgage_used? + return unless record.mortgage + + if over_tolerance?(record.mortgage_deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1) + %i[mortgage value deposit cashdis equity].each do |field| + record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + elsif record.mortgage_not_used? + if over_tolerance?(record.deposit_and_discount_total, record.expected_shared_ownership_deposit_value, 1) + %i[mortgageused value deposit cashdis equity].each do |field| + record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) + end + end + end + def check_non_staircasing_non_socialhomebuy_mortgage(record) if record.mortgage_used? return unless record.mortgage - if record.mortgage_and_deposit_total != record.expected_shared_ownership_deposit_value + if over_tolerance?(record.mortgage_and_deposit_total, record.expected_shared_ownership_deposit_value, 1) %i[mortgage value deposit equity].each do |field| record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end elsif record.mortgage_not_used? - if record.deposit != record.expected_shared_ownership_deposit_value + if over_tolerance?(record.deposit, record.expected_shared_ownership_deposit_value, 1) %i[mortgageused value deposit equity].each do |field| record.errors.add field, I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.non_staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), expected_shared_ownership_deposit_value: record.field_formatted_as_currency("expected_shared_ownership_deposit_value")) end end end - def validate_staircasing_mortgage(record) - return unless record.mortgageused && record.value && record.deposit && record.stairbought - return unless record.is_staircase? - return unless record.saledate && record.form.start_year_after_2024? + def check_staircasing_socialhomebuy_mortgage(record) + return unless record.cashdis if record.mortgage_used? return unless record.mortgage - if record.mortgage_and_deposit_total != record.stairbought_part_of_value - %i[mortgage value deposit stairbought].each do |field| - record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + if over_tolerance?(record.mortgage_deposit_and_discount_total, record.stairbought_part_of_value, 1) + %i[mortgage value deposit cashdis stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used_socialhomebuy", mortgage_deposit_and_discount_total: record.field_formatted_as_currency("mortgage_deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end - elsif record.deposit != record.stairbought_part_of_value - %i[mortgageused value deposit stairbought].each do |field| - record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + elsif over_tolerance?(record.deposit_and_discount_total, record.stairbought_part_of_value, 1) + %i[mortgageused value deposit cashdis stairbought].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used_socialhomebuy", deposit_and_discount_total: record.field_formatted_as_currency("deposit_and_discount_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end end - def validate_mortgage_used_and_stairbought(record) - return unless record.stairowned && record.mortgageused + def check_staircasing_non_socialhomebuy_mortgage(record) + if record.mortgage_used? + return unless record.mortgage - if !record.stairowned_100? && record.mortgageused == 3 - record.errors.add :stairowned, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") - record.errors.add :mortgageused, I18n.t("validations.sale_information.stairowned.mortgageused_dont_know") + if over_tolerance?(record.mortgage_and_deposit_total, record.stairbought_part_of_value, 1) + %i[mortgage value deposit stairbought type].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_used", mortgage_and_deposit_total: record.field_formatted_as_currency("mortgage_and_deposit_total"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + end + elsif over_tolerance?(record.deposit, record.stairbought_part_of_value, 1) + %i[mortgageused value deposit stairbought type].each do |field| + record.errors.add field, I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) + end + record.errors.add :type, :skip_bu_error, message: I18n.t("validations.sale_information.staircasing_mortgage.mortgage_not_used", deposit: record.field_formatted_as_currency("deposit"), stairbought_part_of_value: record.field_formatted_as_currency("stairbought_part_of_value")) end end @@ -170,4 +232,8 @@ module Validations::Sales::SaleInformationValidations record.errors.add(:mortgageused, I18n.t("validations.invalid_option", question: "Was a mortgage used for the purchase of this property?")) end end + + def over_tolerance?(expected, actual, tolerance) + (expected - actual).abs >= tolerance + end end diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index 14c0afae4..51326a2f4 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -1,4 +1,6 @@ module Validations::Sales::SoftValidations + include Validations::Sales::SaleInformationValidations + ALLOWED_INCOME_RANGES_SALES = { 1 => OpenStruct.new(soft_min: 5000), 2 => OpenStruct.new(soft_min: 1500), @@ -86,14 +88,10 @@ module Validations::Sales::SoftValidations def shared_ownership_deposit_invalid? return unless saledate && collection_start_year <= 2023 return unless mortgage || mortgageused == 2 || mortgageused == 3 - return unless cashdis || !is_type_discount? + return unless cashdis || !social_homebuy? return unless deposit && value && equity - !within_tolerance?(mortgage_deposit_and_discount_total, value * equity / 100, 1) - end - - def within_tolerance?(expected, actual, tolerance) - (expected - actual).abs <= tolerance + over_tolerance?(mortgage_deposit_and_discount_total, value * equity / 100, 1) end def mortgage_plus_deposit_less_than_discounted_value? diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index f1124f79d..87d6b491c 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -513,6 +513,7 @@ class BulkUpload::Sales::Year2024::RowParser fields.each do |field| next if errors.include?(field) + next if error.type == :skip_bu_error question = log.form.get_question(error.attribute, log) @@ -721,16 +722,16 @@ private lanomagr: %i[field_97], frombeds: %i[field_98], fromprop: %i[field_99], - value: %i[field_101 field_114 field_125], + value: value_fields, equity: %i[field_102], - mortgage: %i[field_104 field_118 field_127], - extrabor: %i[field_108 field_122 field_129], - deposit: %i[field_109 field_123 field_130], + mortgage: mortgage_fields, + extrabor: extrabor_fields, + deposit: deposit_fields, cashdis: %i[field_110], mrent: %i[field_111], - has_mscharge: %i[field_112 field_124 field_131], - mscharge: %i[field_112 field_124 field_131], + has_mscharge: mscharge_fields, + mscharge: mscharge_fields, grant: %i[field_115], discount: %i[field_116], othtype: %i[field_12], @@ -741,12 +742,12 @@ private hhregresstill: %i[field_73], armedforcesspouse: %i[field_74], - mortgagelender: %i[field_105 field_119], - mortgagelenderother: %i[field_106 field_120], + mortgagelender: mortgagelender_fields, + mortgagelenderother: mortgagelenderother_fields, hb: %i[field_81], - mortlen: %i[field_107 field_121 field_128], - proplen: %i[field_113 field_85], + mortlen: mortlen_fields, + proplen: proplen_fields, jointmore: %i[field_16], staircase: %i[field_86], @@ -762,7 +763,7 @@ private stairbought: %i[field_87], stairowned: %i[field_88], socprevten: %i[field_100], - mortgageused: [mortgageused_field], + mortgageused: mortgageused_fields, uprn: %i[field_22], address_line1: %i[field_23], @@ -1118,10 +1119,81 @@ private return field_126 if outright_sale? end - def mortgageused_field - return :field_103 if shared_ownership? - return :field_117 if discounted_ownership? - return :field_126 if outright_sale? + def value_fields + return [:field_101] if shared_ownership? + return [:field_114] if discounted_ownership? + return [:field_125] if outright_sale? + + %i[field_101 field_114 field_125] + end + + def mortgage_fields + return [:field_104] if shared_ownership? + return [:field_118] if discounted_ownership? + return [:field_127] if outright_sale? + + %i[field_104 field_118 field_127] + end + + def extrabor_fields + return [:field_108] if shared_ownership? + return [:field_122] if discounted_ownership? + return [:field_129] if outright_sale? + + %i[field_108 field_122 field_129] + end + + def deposit_fields + return [:field_109] if shared_ownership? + return [:field_123] if discounted_ownership? + return [:field_130] if outright_sale? + + %i[field_109 field_123 field_130] + end + + def mscharge_fields + return [:field_112] if shared_ownership? + return [:field_124] if discounted_ownership? + return [:field_131] if outright_sale? + + %i[field_112 field_124 field_131] + end + + def mortgagelender_fields + return [:field_105] if shared_ownership? + return [:field_119] if discounted_ownership? + + %i[field_105 field_119] + end + + def mortgagelenderother_fields + return [:field_106] if shared_ownership? + return [:field_120] if discounted_ownership? + + %i[field_106 field_120] + end + + def mortlen_fields + return [:field_107] if shared_ownership? + return [:field_121] if discounted_ownership? + return [:field_128] if outright_sale? + + %i[field_107 field_121 field_128] + end + + def proplen_fields + return [:field_85] if shared_ownership? + return [:field_113] if discounted_ownership? + + %i[field_85 field_113] + end + + def mortgageused_fields + return [:field_103] if shared_ownership? + return [:field_117] if discounted_ownership? + return [:field_126] if outright_sale? + + %i[field_103 field_117 field_126] end def owning_organisation diff --git a/config/locales/en.yml b/config/locales/en.yml index afbba3e2c..2f3e63020 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -641,11 +641,15 @@ en: over_discounted_london_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £136,400 for properties in London." over_discounted_max: "The percentage discount multiplied by the purchase price is %{discount_value}. This figure should not be more than £102,400 for properties outside of London." non_staircasing_mortgage: - mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. These figures should be the same." - mortgage_not_used: "The deposit is %{deposit} and the purchase price times by the equity is %{expected_shared_ownership_deposit_value}. As no mortgage was used, these figures should be the same." + mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_not_used: "The deposit is %{deposit} and the value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_used_socialhomebuy: "The mortgage, deposit, and cash discount added together is %{mortgage_deposit_and_discount_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." + mortgage_not_used_socialhomebuy: "The deposit and cash discount added together is %{deposit_and_discount_total}. The value multiplied by the percentage bought is %{expected_shared_ownership_deposit_value}. These figures should be the same." staircasing_mortgage: - mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total} and the percentage bought times the purchase price is %{stairbought_part_of_value}. These figures should be the same." - mortgage_not_used: "The deposit is %{deposit} and the percentage bought times the purchase price is %{stairbought_part_of_value}. As no mortgage was used, these figures should be the same." + mortgage_used: "The mortgage and deposit added together is %{mortgage_and_deposit_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_not_used: "The deposit is %{deposit} and the value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_used_socialhomebuy: "The mortgage, deposit, and cash discount added together is %{mortgage_deposit_and_discount_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." + mortgage_not_used_socialhomebuy: "The deposit and cash discount added together is %{deposit_and_discount_total}. The value multiplied by the percentage bought is %{stairbought_part_of_value}. These figures should be the same." stairowned: mortgageused_dont_know: "The percentage owned has to be 100% if the mortgage used is 'Don’t know'" merge_request: diff --git a/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb index 4cffb2b54..fabfb7836 100644 --- a/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb +++ b/spec/models/form/sales/pages/about_deposit_with_discount_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true }], + [{ "social_homebuy?" => true }], ) end @@ -42,7 +42,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true }], + [{ "social_homebuy?" => true }], ) end end @@ -54,7 +54,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true, "stairowned_100?" => false }], + [{ "social_homebuy?" => true, "stairowned_100?" => false }], ) end @@ -63,7 +63,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => true, "stairowned_100?" => true }], + [{ "social_homebuy?" => true, "stairowned_100?" => true }], ) end end diff --git a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb index d6f58c65f..003313353 100644 --- a/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb +++ b/spec/models/form/sales/pages/about_deposit_without_discount_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -44,7 +44,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1 }, + [{ "social_homebuy?" => false, "ownershipsch" => 1 }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -58,7 +58,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => false }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => false }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) @@ -69,7 +69,7 @@ RSpec.describe Form::Sales::Pages::AboutDepositWithoutDiscount, type: :model do it "has correct depends_on" do expect(page.depends_on).to eq( - [{ "is_type_discount?" => false, "ownershipsch" => 1, "stairowned_100?" => true }, + [{ "social_homebuy?" => false, "ownershipsch" => 1, "stairowned_100?" => true }, { "ownershipsch" => 2 }, { "ownershipsch" => 3, "mortgageused" => 1 }], ) diff --git a/spec/models/validations/sales/financial_validations_spec.rb b/spec/models/validations/sales/financial_validations_spec.rb index e52387987..316c2d175 100644 --- a/spec/models/validations/sales/financial_validations_spec.rb +++ b/spec/models/validations/sales/financial_validations_spec.rb @@ -432,181 +432,6 @@ RSpec.describe Validations::Sales::FinancialValidations do end end - describe "#validate_shared_ownership_deposit" do - let(:record) { FactoryBot.create(:sales_log, saledate: now) } - - around do |example| - Timecop.freeze(now) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - end - - context "with a log in the 24/25 collection year" do - let(:now) { Time.zone.local(2024, 4, 2) } - - it "does not add an error if MORTGAGE + DEPOSIT + CASHDIS are equal VALUE * EQUITY/100" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if mortgage is used and no mortgage is given" do - record.mortgage = nil - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "adds an error if mortgage is not used and no mortgage is given" do - record.mortgage = nil - record.mortgageused = 2 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £2,000.00. The value times the equity percentage is £3,000.00. These figures should be the same") - end - - it "does not add an error if no deposit is given" do - record.mortgage = 1000 - record.deposit = nil - record.cashdis = 1000 - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no cashdis is given and cashdis is routed to" do - record.mortgage = 1000 - record.deposit = 1000 - record.type = 18 - record.cashdis = nil - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no cashdis is given and cashdis is not routed to" do - record.mortgageused = 1 - record.mortgage = 1000 - record.deposit = 1000 - record.type = 2 - record.cashdis = nil - record.value = 3000 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no value is given" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = nil - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "does not add an error if no equity is given" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 3000 - record.equity = nil - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - - it "adds an error if MORTGAGE + DEPOSIT + CASHDIS are not equal VALUE * EQUITY/100" do - record.mortgageused = 1 - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 4323 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £3,000.00. The value times the equity percentage is £4,323.00. These figures should be the same") - end - end - - context "with a log in 23/24 collection year" do - let(:now) { Time.zone.local(2024, 1, 1) } - - it "does not add an error if MORTGAGE + DEPOSIT + CASHDIS are not equal VALUE * EQUITY/100" do - record.mortgage = 1000 - record.deposit = 1000 - record.cashdis = 1000 - record.value = 4323 - record.equity = 100 - - financial_validator.validate_shared_ownership_deposit(record) - expect(record.errors["mortgage"]).to be_empty - expect(record.errors["deposit"]).to be_empty - expect(record.errors["cashdis"]).to be_empty - expect(record.errors["value"]).to be_empty - expect(record.errors["equity"]).to be_empty - end - end - end - describe "#validate_equity_less_than_staircase_difference" do let(:record) { FactoryBot.create(:sales_log, saledate: now) } diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index ca07da6f4..4da297f53 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -740,10 +740,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_non_staircasing_mortgage(record) - expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity is £8,400.00. These figures should be the same.") - expect(record.errors["value"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity is £8,400.00. These figures should be the same.") - expect(record.errors["deposit"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity is £8,400.00. These figures should be the same.") - expect(record.errors["equity"]).to include("The mortgage and deposit added together is £15,000.00 and the purchase price times by the equity is £8,400.00. These figures should be the same.") + expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -758,12 +793,14 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end context "when MORTGAGE + DEPOSIT equals VALUE * EQUITY/100" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, staircase: 2, deposit: 5_000, value: 30_000, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 2, deposit: 5_000, value: 30_000, equity: 50, ownershipsch: 1, type: 30, saledate: now) } it "does not add an error" do sale_information_validator.validate_non_staircasing_mortgage(record) @@ -771,6 +808,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when MORTGAGE + DEPOSIT is within 1£ tolerance of VALUE * EQUITY/100" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 2, deposit: 50_000, value: 120_001, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end @@ -787,10 +840,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_non_staircasing_mortgage(record) - expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["value"]).to include("The deposit is £5,000.00 and the purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["equity"]).to include("The deposit is £5,000.00 and the purchase price times by the equity is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["equity"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -805,6 +893,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -818,6 +908,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when DEPOSIT is within 1£ tolerance of VALUE * EQUITY/100" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 2, deposit: 15_000, value: 30_001, equity: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -833,6 +939,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["equity"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -860,10 +968,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_staircasing_mortgage(record) - expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") - expect(record.errors["value"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") - expect(record.errors["deposit"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") - expect(record.errors["stairbought"]).to include("The mortgage and deposit added together is £15,000.00 and the percentage bought times the purchase price is £8,400.00. These figures should be the same.") + expect(record.errors["mortgage"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The mortgage, deposit, and cash discount added together is £15,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -878,12 +1021,14 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end context "when MORTGAGE + DEPOSIT equals STAIRBOUGHT/100 * VALUE" do - let(:record) { FactoryBot.build(:sales_log, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_000, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_000, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } it "does not add an error" do sale_information_validator.validate_staircasing_mortgage(record) @@ -891,6 +1036,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when MORTGAGE + DEPOSIT is within 1£ tolerance of STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 1, mortgage: 10_000, staircase: 1, deposit: 5_000, value: 30_001, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgage"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -905,6 +1066,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end @@ -924,10 +1087,45 @@ RSpec.describe Validations::Sales::SaleInformationValidations do it "adds an error" do sale_information_validator.validate_staircasing_mortgage(record) - expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["value"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") - expect(record.errors["stairbought"]).to include("The deposit is £5,000.00 and the percentage bought times the purchase price is £8,400.00. As no mortgage was used, these figures should be the same.") + expect(record.errors["mortgageused"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).not_to include("The deposit is £5,000.00 and the value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + context "and it is a social homebuy" do + before do + record.type = 18 + record.cashdis = "200" + end + + it "adds an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["value"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["deposit"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["stairbought"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["cashdis"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(record.errors["type"]).to include("The deposit and cash discount added together is £5,200.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + end + + context "and it is not a shared ownership transaction" do + before do + record.ownershipsch = 2 + end + + it "does not add an error" do + sale_information_validator.validate_non_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end end end @@ -942,6 +1140,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -955,6 +1155,22 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty + end + end + + context "when DEPOSIT is within 1£ tolerance of STAIRBOUGHT/100 * VALUE" do + let(:record) { FactoryBot.build(:sales_log, mortgageused: 2, staircase: 1, deposit: 15_000, value: 30_001, stairbought: 50, ownershipsch: 1, type: 30, saledate: now) } + + it "does not add an error" do + sale_information_validator.validate_staircasing_mortgage(record) + expect(record.errors["mortgageused"]).to be_empty + expect(record.errors["value"]).to be_empty + expect(record.errors["deposit"]).to be_empty + expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end @@ -969,6 +1185,8 @@ RSpec.describe Validations::Sales::SaleInformationValidations do expect(record.errors["value"]).to be_empty expect(record.errors["deposit"]).to be_empty expect(record.errors["stairbought"]).to be_empty + expect(record.errors["cashdis"]).to be_empty + expect(record.errors["type"]).to be_empty end end end diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb index 93ab6d9da..e68e95f06 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb @@ -1134,6 +1134,32 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do expect(parser.errors[:field_109]).to be_empty end end + + context "with non staircasing mortgage error" do + let(:attributes) { setup_section_params.merge(field_9: "30", field_103: "1", field_104: "10000", field_109: "5000", field_101: "30000", field_102: "28", field_86: "2") } + + it "does not add a BU error on type (because it's a setup field and would block log creation)" do + expect(parser.errors[:field_9]).to be_empty + end + + it "includes errors on other related fields" do + expect(parser.errors[:field_104]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_109]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_101]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + expect(parser.errors[:field_102]).to include("The mortgage and deposit added together is £15,000.00. The value multiplied by the percentage bought is £8,400.00. These figures should be the same.") + end + + it "does not add errors to other ownership type fields" do + expect(parser.errors[:field_117]).to be_empty + expect(parser.errors[:field_126]).to be_empty + expect(parser.errors[:field_118]).to be_empty + expect(parser.errors[:field_127]).to be_empty + expect(parser.errors[:field_123]).to be_empty + expect(parser.errors[:field_130]).to be_empty + expect(parser.errors[:field_114]).to be_empty + expect(parser.errors[:field_125]).to be_empty + end + end end describe "#field_117" do From 24dfdbe5eb067ef06592c9bcc567045640bc4511 Mon Sep 17 00:00:00 2001 From: natdeanlewissoftwire <94526761+natdeanlewissoftwire@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:51:04 +0000 Subject: [PATCH 2/4] CLDC-3271 Add address fields as entered in bulk upload to support csv downloads (#2322) * feat: add bulk upload address info to lettings csv download * feat: add bulk upload address info to sales csv download * refactor: lint * feat: fix typo * feat: update tests * feat: add to non question fields * feat: update tests * feat: add sales tests * feat: add as entered fields to xml export for 2024 only (#2324) * feat: update schema --- app/jobs/email_csv_job.rb | 2 +- .../bulk_upload/lettings/year2024/row_parser.rb | 6 ++++++ .../bulk_upload/sales/year2024/row_parser.rb | 6 ++++++ app/services/csv/lettings_log_csv_service.rb | 4 ++-- app/services/csv/sales_log_csv_service.rb | 10 +++++++--- .../exports/lettings_log_export_constants.rb | 16 ++++++++++++++-- .../exports/lettings_log_export_service.rb | 4 ---- ...dd_entered_address_fields_to_lettings_logs.rb | 12 ++++++++++++ ...7_add_entered_address_fields_to_sales_logs.rb | 12 ++++++++++++ db/schema.rb | 12 ++++++++++++ .../fixtures/exports/general_needs_log_24_25.xml | 6 ++++++ .../files/lettings_log_csv_export_codes_23.csv | 4 ++-- .../files/lettings_log_csv_export_codes_24.csv | 4 ++-- .../files/lettings_log_csv_export_labels_23.csv | 4 ++-- .../files/lettings_log_csv_export_labels_24.csv | 4 ++-- .../files/sales_logs_csv_export_codes_23.csv | 4 ++-- .../files/sales_logs_csv_export_codes_24.csv | 4 ++-- .../files/sales_logs_csv_export_labels_23.csv | 4 ++-- .../files/sales_logs_csv_export_labels_24.csv | 4 ++-- spec/jobs/email_csv_job_spec.rb | 4 ++-- .../csv/lettings_log_csv_service_spec.rb | 6 ++++++ spec/services/csv/sales_log_csv_service_spec.rb | 12 +++++++++--- .../exports/lettings_log_export_service_spec.rb | 2 +- 23 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 db/migrate/20240319092425_add_entered_address_fields_to_lettings_logs.rb create mode 100644 db/migrate/20240319115447_add_entered_address_fields_to_sales_logs.rb diff --git a/app/jobs/email_csv_job.rb b/app/jobs/email_csv_job.rb index 89b358e28..7658cf755 100644 --- a/app/jobs/email_csv_job.rb +++ b/app/jobs/email_csv_job.rb @@ -15,7 +15,7 @@ class EmailCsvJob < ApplicationJob 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) - csv_string = Csv::SalesLogCsvService.new(export_type:).prepare_csv(filtered_logs) + csv_string = Csv::SalesLogCsvService.new(user:, export_type:).prepare_csv(filtered_logs) end filename = "#{[log_type, 'logs', organisation&.name, Time.zone.now].compact.join('-')}.csv" diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb index 8b5fe8f3c..b0802df12 100644 --- a/app/services/bulk_upload/lettings/year2024/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb @@ -1092,6 +1092,7 @@ private attributes["lettype"] = nil # should get this from rent_type attributes["tenancycode"] = field_13 attributes["la"] = field_23 + attributes["la_as_entered"] = field_23 attributes["postcode_known"] = postcode_known attributes["postcode_full"] = postcode_full attributes["owning_organisation"] = owning_organisation @@ -1268,11 +1269,16 @@ private attributes["skip_update_uprn_confirmed"] = true attributes["uprn"] = field_16 attributes["address_line1"] = field_17 + attributes["address_line1_as_entered"] = field_17 attributes["address_line2"] = field_18 + attributes["address_line2_as_entered"] = field_18 attributes["town_or_city"] = field_19 + attributes["town_or_city_as_entered"] = field_19 attributes["county"] = field_20 + attributes["county_as_entered"] = field_20 attributes["address_line1_input"] = address_line1_input attributes["postcode_full_input"] = postcode_full + attributes["postcode_full_as_entered"] = postcode_full attributes["select_best_address_match"] = true if field_16.blank? attributes diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index 87d6b491c..be6a9ca63 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -874,9 +874,11 @@ private attributes["builtype"] = field_21 attributes["la_known"] = field_29.present? ? 1 : 0 attributes["la"] = field_29 + attributes["la_as_entered"] = field_29 attributes["is_la_inferred"] = false attributes["pcodenk"] = 0 if postcode_full.present? attributes["postcode_full"] = postcode_full + attributes["postcode_full_as_entered"] = postcode_full attributes["wchair"] = field_30 attributes["type"] = sale_type @@ -942,9 +944,13 @@ private attributes["uprn_confirmed"] = 1 if field_22.present? attributes["skip_update_uprn_confirmed"] = true attributes["address_line1"] = field_23 + attributes["address_line1_as_entered"] = field_23 attributes["address_line2"] = field_24 + attributes["address_line2_as_entered"] = field_24 attributes["town_or_city"] = field_25 + attributes["town_or_city_as_entered"] = field_25 attributes["county"] = field_26 + attributes["county_as_entered"] = field_26 attributes["address_line1_input"] = address_line1_input attributes["postcode_full_input"] = postcode_full attributes["select_best_address_match"] = true if field_22.blank? diff --git a/app/services/csv/lettings_log_csv_service.rb b/app/services/csv/lettings_log_csv_service.rb index 2dd817ebe..c32b82cc7 100644 --- a/app/services/csv/lettings_log_csv_service.rb +++ b/app/services/csv/lettings_log_csv_service.rb @@ -296,7 +296,7 @@ module Csv "letting_allocation_unknown" => %w[letting_allocation_none], }.freeze - SUPPORT_ONLY_ATTRIBUTES = %w[net_income_value_check first_time_property_let_as_social_housing postcode_known is_la_inferred totchild totelder totadult net_income_known previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 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 la prevloc updated_by_id bulk_upload_id uprn_confirmed address_line1_input postcode_full_input address_search_value_check uprn_selection reasonother_value_check].freeze + SUPPORT_ONLY_ATTRIBUTES = %w[net_income_value_check first_time_property_let_as_social_housing postcode_known is_la_inferred totchild totelder totadult net_income_known previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 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 la prevloc updated_by_id bulk_upload_id uprn_confirmed address_line1_input postcode_full_input address_search_value_check uprn_selection reasonother_value_check address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered].freeze def lettings_log_attributes ordered_questions = FormHandler.instance.ordered_lettings_questions_for_all_years @@ -310,7 +310,7 @@ module Csv ATTRIBUTE_MAPPINGS.fetch(question.id, question.id) end end - non_question_fields = %w[id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year] + non_question_fields = %w[id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered] 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_local_authority location_startdate] final_attributes = non_question_fields + attributes + scheme_and_location_attributes @user.support? ? final_attributes : final_attributes - SUPPORT_ONLY_ATTRIBUTES diff --git a/app/services/csv/sales_log_csv_service.rb b/app/services/csv/sales_log_csv_service.rb index a1fbc1ca9..c0d030842 100644 --- a/app/services/csv/sales_log_csv_service.rb +++ b/app/services/csv/sales_log_csv_service.rb @@ -1,6 +1,7 @@ module Csv class SalesLogCsvService - def initialize(export_type:) + def initialize(user:, export_type:) + @user = user @export_type = export_type @attributes = sales_log_attributes end @@ -132,6 +133,8 @@ module Csv "managing_organisation_id" => %w[managing_organisation_name], }.freeze + SUPPORT_ONLY_ATTRIBUTES = %w[address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered].freeze + def sales_log_attributes ordered_questions = FormHandler.instance.ordered_sales_questions_for_all_years ordered_questions.reject! { |q| q.id.match?(/((? 2 + address line 1 as entered + address line 2 as entered + town or city as entered + county as entered + AB1 2CD + la as entered {id} {owning_org_id} DLUHC diff --git a/spec/fixtures/files/lettings_log_csv_export_codes_23.csv b/spec/fixtures/files/lettings_log_csv_export_codes_23.csv index 5071b4a09..547d2f5b1 100644 --- a/spec/fixtures/files/lettings_log_csv_export_codes_23.csv +++ b/spec/fixtures/files/lettings_log_csv_export_codes_23.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,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,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate -,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,0,,,,,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,1,4,,1,4,0,0,2,35,,F,0,2,,13,0,0,P,,,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,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,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,,2,,0,0,1,268,,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,,,,,,,,,,,,,,,,,,,, +id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate +,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,1,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,0,,,,,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,1,4,,1,4,0,0,2,35,,F,0,2,,13,0,0,P,,,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,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,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,,2,,0,0,1,268,,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,,,,,,,,,,,,,,,,,,,, diff --git a/spec/fixtures/files/lettings_log_csv_export_codes_24.csv b/spec/fixtures/files/lettings_log_csv_export_codes_24.csv index c73ad3ab7..e2ef9674e 100644 --- a/spec/fixtures/files/lettings_log_csv_export_codes_24.csv +++ b/spec/fixtures/files/lettings_log_csv_export_codes_24.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,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,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate -,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,1,,,2023,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,1,0,,,,,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,4,,1,4,0,0,2,35,,F,0,2,13,,0,0,P,,,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,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,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,0,,2,,0,0,1,268,,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,,,,,,,,,,,,,,,,,,,, +id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate +,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,1,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,1,7,0,2023-11-26,2,2,1,,2,HIJKLMN,ABCDEFG,1,1,0,,,,,,,fake address,,London,,NW9 5LL,false,Barnet,E09000003,0,2,6,2,2,7,1,1,3,2023-11-24,,,1,2023-11-25,,3,1,4,,2,,4,,1,4,0,0,2,35,,F,0,2,13,,0,0,P,,,32,M,6,1,R,-9,R,10,0,R,-9,R,10,,,,,,,,,,,,,,,,,,,,,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,0,TN23 6LZ,1,false,Ashford,E07000105,1,0,1,0,0,0,0,0,1,0,,2,,0,0,1,268,,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,,,,,,,,,,,,,,,,,,,, diff --git a/spec/fixtures/files/lettings_log_csv_export_labels_23.csv b/spec/fixtures/files/lettings_log_csv_export_labels_23.csv index 638212806..ce4e13518 100644 --- a/spec/fixtures/files/lettings_log_csv_export_labels_23.csv +++ b/spec/fixtures/files/lettings_log_csv_export_labels_23.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,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,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate -,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,,,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,,Yes,4,0,0,2,35,,Female,White,Irish,,Tenant prefers not to say,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,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,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,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,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,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,,,,,,,,,,,,,,,,,,,, +id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate +,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2023-11-26T00:00:00+00:00,single log,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,Yes,4,,Yes,4,0,0,2,35,,Female,White,Irish,,Tenant prefers not to say,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,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,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,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,,Yes,,,,No,No,Yes,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,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,,,,,,,,,,,,,,,,,,,, diff --git a/spec/fixtures/files/lettings_log_csv_export_labels_24.csv b/spec/fixtures/files/lettings_log_csv_export_labels_24.csv index bbe790ef1..378e3150f 100644 --- a/spec/fixtures/files/lettings_log_csv_export_labels_24.csv +++ b/spec/fixtures/files/lettings_log_csv_export_labels_24.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,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,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate -,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,,,2023,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,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,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,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,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,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,,,,,,,,,,,,,,,,,,,, +id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,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,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,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,reasonother_value_check,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,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,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,scharge_value_check,pscharge_value_check,supcharg_value_check,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_local_authority,location_startdate +,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,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,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,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,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,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,,,,,,,,,,,,,,,,,,,, diff --git a/spec/fixtures/files/sales_logs_csv_export_codes_23.csv b/spec/fixtures/files/sales_logs_csv_export_codes_23.csv index 0ecac1947..474487bbf 100644 --- a/spec/fixtures/files/sales_logs_csv_export_codes_23.csv +++ b/spec/fixtures/files/sales_logs_csv_export_codes_23.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,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,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,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,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,1,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,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,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,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 diff --git a/spec/fixtures/files/sales_logs_csv_export_codes_24.csv b/spec/fixtures/files/sales_logs_csv_export_codes_24.csv index 4182589ff..b4b5befa3 100644 --- a/spec/fixtures/files/sales_logs_csv_export_codes_24.csv +++ b/spec/fixtures/files/sales_logs_csv_export_codes_24.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,1,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,1,1,0,1,30,X,17,17,18,,1,1,P,35,X,17,,13,,1,1,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,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,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,1,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,2,8,,,,1,1,2,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,1,1,0,1,30,X,17,17,18,,1,1,P,35,X,17,,13,,1,1,3,C,14,X,,X,-9,X,3,R,-9,R,10,,,,,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 diff --git a/spec/fixtures/files/sales_logs_csv_export_labels_23.csv b/spec/fixtures/files/sales_logs_csv_export_labels_23.csv index ca7b4b1b7..d299a2612 100644 --- a/spec/fixtures/files/sales_logs_csv_export_labels_23.csv +++ b/spec/fixtures/files/sales_logs_csv_export_labels_23.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,0,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer prefers not to say,17,,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Buyer prefers not to say,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 +id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,beds,proptype,builtype,pcodenk,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,wchair,noint,privacynotice,age1,sex1,ethnic_group,ethnic,nationality_all,national,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-01-01T00:00:00+00:00,,2023,single log,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,2,Flat or maisonette,Purpose built,0,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,Yes,Yes,1,30,Non-binary,Buyer prefers not to say,17,,United Kingdom,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,,Buyer prefers not to say,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 diff --git a/spec/fixtures/files/sales_logs_csv_export_labels_24.csv b/spec/fixtures/files/sales_logs_csv_export_labels_24.csv index 44c97dd06..833173e3b 100644 --- a/spec/fixtures/files/sales_logs_csv_export_labels_24.csv +++ b/spec/fixtures/files/sales_logs_csv_export_labels_24.csv @@ -1,2 +1,2 @@ -id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,single log,false,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 +id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,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-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,single log,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 diff --git a/spec/jobs/email_csv_job_spec.rb b/spec/jobs/email_csv_job_spec.rb index 61d5dca74..791c1ec1a 100644 --- a/spec/jobs/email_csv_job_spec.rb +++ b/spec/jobs/email_csv_job_spec.rb @@ -90,10 +90,10 @@ describe EmailCsvJob do end it "creates a SalesLogCsvService with the correct export type" do - expect(Csv::SalesLogCsvService).to receive(:new).with(export_type: "labels") + expect(Csv::SalesLogCsvService).to receive(:new).with(user:, export_type: "labels") codes_only = false job.perform(user, nil, {}, nil, nil, codes_only, "sales") - expect(Csv::SalesLogCsvService).to receive(:new).with(export_type: "codes") + expect(Csv::SalesLogCsvService).to receive(:new).with(user:, export_type: "codes") codes_only = true job.perform(user, nil, {}, nil, nil, codes_only, "sales") end diff --git a/spec/services/csv/lettings_log_csv_service_spec.rb b/spec/services/csv/lettings_log_csv_service_spec.rb index 7109d0e94..c0232ef5d 100644 --- a/spec/services/csv/lettings_log_csv_service_spec.rb +++ b/spec/services/csv/lettings_log_csv_service_spec.rb @@ -41,6 +41,12 @@ RSpec.describe Csv::LettingsLogCsvService do relat4: "R", age4_known: 1, incref: 0, + address_line1_as_entered: "address line 1 as entered", + address_line2_as_entered: "address line 2 as entered", + town_or_city_as_entered: "town or city as entered", + county_as_entered: "county as entered", + postcode_full_as_entered: "AB1 2CD", + la_as_entered: "la as entered", ) end let(:user) { create(:user, :support, email: "s.port@jeemayle.com") } diff --git a/spec/services/csv/sales_log_csv_service_spec.rb b/spec/services/csv/sales_log_csv_service_spec.rb index 79efaf920..e34595942 100644 --- a/spec/services/csv/sales_log_csv_service_spec.rb +++ b/spec/services/csv/sales_log_csv_service_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Csv::SalesLogCsvService do let(:organisation) { create(:organisation) } let(:fixed_time) { Time.zone.local(2023, 12, 8) } let(:now) { Time.zone.now } - let(:user) { create(:user, email: "billyboy@eyeKLAUD.com") } + let(:user) { create(:user, :support, email: "billyboy@eyeKLAUD.com") } let(:log) do create( :sales_log, @@ -24,9 +24,15 @@ RSpec.describe Csv::SalesLogCsvService do ecstat6: nil, relat6: nil, sex6: nil, + address_line1_as_entered: "address line 1 as entered", + address_line2_as_entered: "address line 2 as entered", + town_or_city_as_entered: "town or city as entered", + county_as_entered: "county as entered", + postcode_full_as_entered: "AB1 2CD", + la_as_entered: "la as entered", ) end - let(:service) { described_class.new(export_type: "labels") } + let(:service) { described_class.new(user:, export_type: "labels") } let(:csv) { CSV.parse(service.prepare_csv(SalesLog.all)) } before do @@ -201,7 +207,7 @@ RSpec.describe Csv::SalesLogCsvService do end context "when exporting values as codes" do - let(:service) { described_class.new(export_type: "codes") } + let(:service) { described_class.new(user:, export_type: "codes") } it "gives answers to radio questions as their codes" do national_column_index = csv.first.index("national") diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb index 6141207d1..2e534f748 100644 --- a/spec/services/exports/lettings_log_export_service_spec.rb +++ b/spec/services/exports/lettings_log_export_service_spec.rb @@ -472,7 +472,7 @@ RSpec.describe Exports::LettingsLogExportService do end context "and one lettings log is available for export" do - let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, created_by: user, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4) } + let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, created_by: user, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered") } let(:expected_zip_filename) { "core_2024_2025_apr_mar_f0001_inc0001.zip" } let(:expected_data_filename) { "core_2024_2025_apr_mar_f0001_inc0001_pt001.xml" } let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_24_25.xml", "r:UTF-8") } From 9dc37f7fff1aa6ccbec213200192a73ab2afd7ff Mon Sep 17 00:00:00 2001 From: Rachael Booth Date: Wed, 20 Mar 2024 15:38:15 +0000 Subject: [PATCH 3/4] CLDC-3304: Add bulk upload id to xml exports from 2024 (#2323) --- app/services/exports/lettings_log_export_constants.rb | 2 ++ spec/fixtures/exports/general_needs_log_24_25.xml | 3 ++- spec/services/exports/lettings_log_export_service_spec.rb | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/services/exports/lettings_log_export_constants.rb b/app/services/exports/lettings_log_export_constants.rb index c60f1339d..0e6edd139 100644 --- a/app/services/exports/lettings_log_export_constants.rb +++ b/app/services/exports/lettings_log_export_constants.rb @@ -141,6 +141,7 @@ module Exports::LettingsLogExportConstants "duplicate_set_id", "accessible_register", "nationality_all", + "bulk_upload_id", "address_line1_as_entered", "address_line2_as_entered", "town_or_city_as_entered", @@ -167,6 +168,7 @@ module Exports::LettingsLogExportConstants POST_2024_EXPORT_FIELDS = Set[ "accessible_register", "nationality_all", + "bulk_upload_id", "address_line1_as_entered", "address_line2_as_entered", "town_or_city_as_entered", diff --git a/spec/fixtures/exports/general_needs_log_24_25.xml b/spec/fixtures/exports/general_needs_log_24_25.xml index f21e20f47..3b27d50af 100644 --- a/spec/fixtures/exports/general_needs_log_24_25.xml +++ b/spec/fixtures/exports/general_needs_log_24_25.xml @@ -134,6 +134,7 @@ 4 2 698 + 1 0 @@ -142,7 +143,7 @@ London - 1 + 2 2 diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb index 2e534f748..dd2230598 100644 --- a/spec/services/exports/lettings_log_export_service_spec.rb +++ b/spec/services/exports/lettings_log_export_service_spec.rb @@ -472,7 +472,7 @@ RSpec.describe Exports::LettingsLogExportService do end context "and one lettings log is available for export" do - let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, created_by: user, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered") } + let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, created_by: user, ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered") } let(:expected_zip_filename) { "core_2024_2025_apr_mar_f0001_inc0001.zip" } let(:expected_data_filename) { "core_2024_2025_apr_mar_f0001_inc0001_pt001.xml" } let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_24_25.xml", "r:UTF-8") } From e52a8238cc41528219921fe94b2412745dcee047 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:44:36 +0000 Subject: [PATCH 4/4] CLDC-3343 Check relat fields for people we collect data for (#2335) * Check relat fields for people we collect data for * rename --- app/models/validations/soft_validations.rb | 3 +- .../sales/soft_validations_spec.rb | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/app/models/validations/soft_validations.rb b/app/models/validations/soft_validations.rb index d5c301066..7be2f5090 100644 --- a/app/models/validations/soft_validations.rb +++ b/app/models/validations/soft_validations.rb @@ -194,7 +194,8 @@ module Validations::SoftValidations def multiple_partners? return unless hhmemb - (2..hhmemb).many? { |n| public_send("relat#{n}") == "P" } + max_person_with_details = sales? ? [hhmemb, 6].min : [hhmemb, 8].min + (2..max_person_with_details).many? { |n| public_send("relat#{n}") == "P" } end private diff --git a/spec/models/validations/sales/soft_validations_spec.rb b/spec/models/validations/sales/soft_validations_spec.rb index 299968436..b64eb1bde 100644 --- a/spec/models/validations/sales/soft_validations_spec.rb +++ b/spec/models/validations/sales/soft_validations_spec.rb @@ -1324,4 +1324,42 @@ RSpec.describe Validations::Sales::SoftValidations do end end end + + describe "#multiple_partners?" do + let(:record) { FactoryBot.create(:sales_log, :completed, ownershipsch: 1, jointpur: 1) } + + context "when there are multiple partners" do + before do + record.hhmemb = 3 + record.relat2 = "P" + record.relat3 = "P" + end + + it "returns true" do + expect(record).to be_multiple_partners + end + end + + context "when there are not multiple partners" do + before do + record.hhmemb = 2 + record.relat2 = "P" + end + + it "returns false" do + expect(record).not_to be_multiple_partners + end + end + + context "when hhmemb is more than the number of person details we require for joint purchase" do + before do + record.hhmemb = 14 + record.relat2 = "P" + end + + it "correctly runs the method" do + expect(record).not_to be_multiple_partners + end + end + end end