diff --git a/app/components/bulk_upload_error_summary_table_component.rb b/app/components/bulk_upload_error_summary_table_component.rb
index ac236af4d..a3d295110 100644
--- a/app/components/bulk_upload_error_summary_table_component.rb
+++ b/app/components/bulk_upload_error_summary_table_component.rb
@@ -1,4 +1,6 @@
class BulkUploadErrorSummaryTableComponent < ViewComponent::Base
+ DISPLAY_THRESHOLD = 16
+
attr_reader :bulk_upload
def initialize(bulk_upload:)
@@ -11,7 +13,18 @@ class BulkUploadErrorSummaryTableComponent < ViewComponent::Base
@sorted_errors ||= bulk_upload
.bulk_upload_errors
.group(:col, :field, :error)
+ .having("count(*) > ?", display_threshold)
.count
.sort_by { |el| el[0][0].rjust(3, "0") }
end
+
+ def errors?
+ sorted_errors.present?
+ end
+
+private
+
+ def display_threshold
+ DISPLAY_THRESHOLD
+ end
end
diff --git a/app/components/check_answers_summary_list_card_component.rb b/app/components/check_answers_summary_list_card_component.rb
index af8ebd36a..e8ed971bc 100644
--- a/app/components/check_answers_summary_list_card_component.rb
+++ b/app/components/check_answers_summary_list_card_component.rb
@@ -18,21 +18,10 @@ class CheckAnswersSummaryListCardComponent < ViewComponent::Base
end
def check_answers_card_title(question)
- if question.form.type == "lettings"
- case question.check_answers_card_number
- when 1
- "Lead tenant"
- when 2..8
- "Person #{question.check_answers_card_number}"
- end
- else
- case question.check_answers_card_number
- when 1..number_of_buyers
- "Buyer #{question.check_answers_card_number}"
- when (number_of_buyers + 1)..(number_of_buyers + 4)
- "Person #{question.check_answers_card_number}"
- end
- end
+ return "Lead tenant" if question.form.type == "lettings" && question.check_answers_card_number == 1
+ return "Buyer #{question.check_answers_card_number}" if question.check_answers_card_number <= number_of_buyers
+
+ "Person #{question.check_answers_card_number}"
end
private
diff --git a/app/mailers/bulk_upload_mailer.rb b/app/mailers/bulk_upload_mailer.rb
index be0a71e05..94079828f 100644
--- a/app/mailers/bulk_upload_mailer.rb
+++ b/app/mailers/bulk_upload_mailer.rb
@@ -46,6 +46,12 @@ class BulkUploadMailer < NotifyMailer
def send_correct_and_upload_again_mail(bulk_upload:)
error_description = "We noticed that you have a lot of similar errors in column #{columns_with_errors(bulk_upload:)}. Please correct your data export and upload again."
+ summary_report_link = if BulkUploadErrorSummaryTableComponent.new(bulk_upload:).errors?
+ summary_bulk_upload_lettings_result_url(bulk_upload)
+ else
+ bulk_upload_lettings_result_url(bulk_upload)
+ end
+
send_email(
bulk_upload.user.email,
BULK_UPLOAD_FAILED_CSV_ERRORS_TEMPLATE_ID,
@@ -55,7 +61,7 @@ class BulkUploadMailer < NotifyMailer
year_combo: bulk_upload.year_combo,
lettings_or_sales: bulk_upload.log_type,
error_description:,
- summary_report_link: summary_bulk_upload_lettings_result_url(bulk_upload),
+ summary_report_link:,
},
)
end
diff --git a/app/models/derived_variables/sales_log_variables.rb b/app/models/derived_variables/sales_log_variables.rb
index 16fb6ebd7..525c12936 100644
--- a/app/models/derived_variables/sales_log_variables.rb
+++ b/app/models/derived_variables/sales_log_variables.rb
@@ -21,12 +21,19 @@ module DerivedVariables::SalesLogVariables
self.pcode1, self.pcode2 = postcode_full.split(" ") if postcode_full.present?
self.totchild = total_child
self.totadult = total_adult + total_elder
- self.hhmemb = totchild + totadult
+ self.hhmemb = number_of_household_members
self.hhtype = household_type
end
private
+ def number_of_household_members
+ return unless hholdcount.present? && jointpur.present?
+
+ number_of_buyers = joint_purchase? ? 2 : 1
+ hholdcount + number_of_buyers
+ end
+
def total_elder
ages = [age1, age2, age3, age4, age5, age6]
ages.count { |age| age.present? && age >= 60 }
diff --git a/app/models/form/sales/pages/number_of_others_in_property.rb b/app/models/form/sales/pages/number_of_others_in_property.rb
index c090422fd..ebf9817bd 100644
--- a/app/models/form/sales/pages/number_of_others_in_property.rb
+++ b/app/models/form/sales/pages/number_of_others_in_property.rb
@@ -1,20 +1,22 @@
class Form::Sales::Pages::NumberOfOthersInProperty < ::Form::Page
- def initialize(id, hsh, subsection)
- super
- @id = "number_of_others_in_property"
+ def initialize(id, hsh, subsection, joint_purchase:)
+ super(id, hsh, subsection)
@depends_on = [
{
"privacynotice" => 1,
+ "jointpur" => joint_purchase ? 1 : 2,
},
{
"noint" => 1,
+ "jointpur" => joint_purchase ? 1 : 2,
},
]
+ @joint_purchase = joint_purchase
end
def questions
@questions ||= [
- Form::Sales::Questions::NumberOfOthersInProperty.new(nil, nil, self),
+ Form::Sales::Questions::NumberOfOthersInProperty.new(nil, nil, self, joint_purchase: @joint_purchase),
]
end
end
diff --git a/app/models/form/sales/questions/buyer1_mortgage.rb b/app/models/form/sales/questions/buyer1_mortgage.rb
index f226f956c..baaf00d4c 100644
--- a/app/models/form/sales/questions/buyer1_mortgage.rb
+++ b/app/models/form/sales/questions/buyer1_mortgage.rb
@@ -2,8 +2,8 @@ class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question
def initialize(id, hsh, page)
super
@id = "inc1mort"
- @check_answer_label = "Buyer 1's income used for mortgage application"
- @header = "Was buyer 1's income used for a mortgage application?"
+ @check_answer_label = "Buyer 1’s income used for mortgage application"
+ @header = "Was buyer 1’s income used for a mortgage application?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 1
@@ -12,5 +12,13 @@ class Form::Sales::Questions::Buyer1Mortgage < ::Form::Question
ANSWER_OPTIONS = {
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
}.freeze
+
+ def displayed_answer_options(_log, _user = nil)
+ {
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
+ }
+ end
end
diff --git a/app/models/form/sales/questions/buyer1_previous_tenure.rb b/app/models/form/sales/questions/buyer1_previous_tenure.rb
index f075e615c..f3482a03f 100644
--- a/app/models/form/sales/questions/buyer1_previous_tenure.rb
+++ b/app/models/form/sales/questions/buyer1_previous_tenure.rb
@@ -2,20 +2,23 @@ class Form::Sales::Questions::Buyer1PreviousTenure < ::Form::Question
def initialize(id, hsh, page)
super
@id = "prevten"
- @check_answer_label = "Buyer 1's previous tenure"
- @header = "What was buyer 1's previous tenure?"
+ @check_answer_label = "Buyer 1’s previous tenure"
+ @header = "What was buyer 1’s previous tenure?"
@type = "radio"
- @answer_options = ANSWER_OPTIONS
+ @answer_options = answer_options
end
- ANSWER_OPTIONS = {
- "1" => { "value" => "Local Authority" },
- "2" => { "value" => "Private registered provider or housing association tenant" },
- "3" => { "value" => "Private tenant" },
- "5" => { "value" => "Owner occupier" },
- "4" => { "value" => "Tied home or renting with job" },
- "6" => { "value" => "Living with family or friends" },
- "7" => { "value" => "Temporary accomodation" },
- "9" => { "value" => "Other" },
- }.freeze
+ def answer_options
+ {
+ "1" => { "value" => "Local Authority" },
+ "2" => { "value" => "Private registered provider or housing association tenant" },
+ "3" => { "value" => "Private tenant" },
+ "5" => { "value" => "Owner occupier" },
+ "4" => { "value" => "Tied home or renting with job" },
+ "6" => { "value" => "Living with family or friends" },
+ "7" => { "value" => "Temporary accomodation" },
+ "9" => { "value" => "Other" },
+ "0" => { "value" => "Don’t know" },
+ }
+ end
end
diff --git a/app/models/form/sales/questions/buyer2_mortgage.rb b/app/models/form/sales/questions/buyer2_mortgage.rb
index 5697aea15..884137df1 100644
--- a/app/models/form/sales/questions/buyer2_mortgage.rb
+++ b/app/models/form/sales/questions/buyer2_mortgage.rb
@@ -2,8 +2,8 @@ class Form::Sales::Questions::Buyer2Mortgage < ::Form::Question
def initialize(id, hsh, page)
super
@id = "inc2mort"
- @check_answer_label = "Buyer 2's income used for mortgage application"
- @header = "Was buyer 2's income used for a mortgage application?"
+ @check_answer_label = "Buyer 2’s income used for mortgage application"
+ @header = "Was buyer 2’s income used for a mortgage application?"
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2
@@ -12,5 +12,13 @@ class Form::Sales::Questions::Buyer2Mortgage < ::Form::Question
ANSWER_OPTIONS = {
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
}.freeze
+
+ def displayed_answer_options(_log, _user = nil)
+ {
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
+ }
+ end
end
diff --git a/app/models/form/sales/questions/buyers_organisations.rb b/app/models/form/sales/questions/buyers_organisations.rb
index 735a1563d..ec76aebcd 100644
--- a/app/models/form/sales/questions/buyers_organisations.rb
+++ b/app/models/form/sales/questions/buyers_organisations.rb
@@ -14,8 +14,18 @@ class Form::Sales::Questions::BuyersOrganisations < ::Form::Question
"pregother" => { "value" => "Other private registered provider (PRP) - housing association" },
"pregla" => { "value" => "Local Authority" },
"pregghb" => { "value" => "Help to Buy Agent" },
+ "pregblank" => { "value" => "None of the above" },
}.freeze
+ def displayed_answer_options(_log, _user = nil)
+ {
+ "pregyrha" => { "value" => "Their private registered provider (PRP) - housing association" },
+ "pregother" => { "value" => "Other private registered provider (PRP) - housing association" },
+ "pregla" => { "value" => "Local Authority" },
+ "pregghb" => { "value" => "Help to Buy Agent" },
+ }
+ end
+
def unanswered_error_message
"At least one option must be selected of these four"
end
diff --git a/app/models/form/sales/questions/mortgageused.rb b/app/models/form/sales/questions/mortgageused.rb
index 8c75750d8..ad18652c4 100644
--- a/app/models/form/sales/questions/mortgageused.rb
+++ b/app/models/form/sales/questions/mortgageused.rb
@@ -11,5 +11,13 @@ class Form::Sales::Questions::Mortgageused < ::Form::Question
ANSWER_OPTIONS = {
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
}.freeze
+
+ def displayed_answer_options(_log, _user = nil)
+ {
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
+ }
+ end
end
diff --git a/app/models/form/sales/questions/number_of_others_in_property.rb b/app/models/form/sales/questions/number_of_others_in_property.rb
index cf590291b..97a873430 100644
--- a/app/models/form/sales/questions/number_of_others_in_property.rb
+++ b/app/models/form/sales/questions/number_of_others_in_property.rb
@@ -1,13 +1,23 @@
class Form::Sales::Questions::NumberOfOthersInProperty < ::Form::Question
- def initialize(id, hsh, page)
- super
+ def initialize(id, hsh, page, joint_purchase:)
+ super(id, hsh, page)
@id = "hholdcount"
@check_answer_label = "Number of other people living in the property"
@header = "Besides the buyer(s), how many other people live or will live in the property?"
@type = "numeric"
- @hint_text = "You can provide details for a maximum of 4 other people."
+ @hint_text = hint(joint_purchase)
@width = 2
@min = 0
- @max = 4
+ @max = joint_purchase ? 4 : 5
+ end
+
+private
+
+ def hint(joint_purchase)
+ if joint_purchase
+ "You can provide details for a maximum of 4 other people for a joint purchase."
+ else
+ "You can provide details for a maximum of 5 other people if there is only one buyer."
+ end
end
end
diff --git a/app/models/form/sales/questions/shared_ownership_type.rb b/app/models/form/sales/questions/shared_ownership_type.rb
index 6351cc185..73b6a4e17 100644
--- a/app/models/form/sales/questions/shared_ownership_type.rb
+++ b/app/models/form/sales/questions/shared_ownership_type.rb
@@ -6,16 +6,31 @@ class Form::Sales::Questions::SharedOwnershipType < ::Form::Question
@header = "What is the type of shared ownership sale?"
@hint_text = "A shared ownership sale is when the purchaser buys up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion"
@type = "radio"
- @answer_options = ANSWER_OPTIONS
+ @answer_options = answer_options
end
- ANSWER_OPTIONS = {
- "2" => { "value" => "Shared Ownership" },
- "24" => { "value" => "Old Persons Shared Ownership" },
- "18" => { "value" => "Social HomeBuy (shared ownership purchase)" },
- "16" => { "value" => "Home Ownership for people with Long Term Disabilities (HOLD)" },
- "28" => { "value" => "Rent to Buy - Shared Ownership" },
- "31" => { "value" => "Right to Shared Ownership" },
- "30" => { "value" => "Shared Ownership - 2021 model lease" },
- }.freeze
+ def answer_options
+ if form.start_date.year >= 2023
+ {
+ "2" => { "value" => "Shared Ownership (old model lease)" },
+ "30" => { "value" => "Shared Ownership (new model lease)" },
+ "18" => { "value" => "Social HomeBuy — shared ownership purchase" },
+ "16" => { "value" => "Home Ownership for people with Long-Term Disabilities (HOLD)" },
+ "24" => { "value" => "Older Persons Shared Ownership" },
+ "28" => { "value" => "Rent to Buy — Shared Ownership" },
+ "31" => { "value" => "Right to Shared Ownership (RtSO)" },
+ "32" => { "value" => "London Living Rent — Shared Ownership" },
+ }
+ else
+ {
+ "2" => { "value" => "Shared Ownership" },
+ "24" => { "value" => "Old Persons Shared Ownership" },
+ "18" => { "value" => "Social HomeBuy (shared ownership purchase)" },
+ "16" => { "value" => "Home Ownership for people with Long-Term Disabilities (HOLD)" },
+ "28" => { "value" => "Rent to Buy - Shared Ownership" },
+ "31" => { "value" => "Right to Shared Ownership" },
+ "30" => { "value" => "Shared Ownership - 2021 model lease" },
+ }
+ end
+ end
end
diff --git a/app/models/form/sales/subsections/household_characteristics.rb b/app/models/form/sales/subsections/household_characteristics.rb
index 181460ae1..571968c8f 100644
--- a/app/models/form/sales/subsections/household_characteristics.rb
+++ b/app/models/form/sales/subsections/household_characteristics.rb
@@ -37,7 +37,8 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::RetirementValueCheck.new("working_situation_2_retirement_value_check_joint_purchase", nil, self, person_index: 2),
Form::Sales::Pages::Buyer2IncomeValueCheck.new("working_situation_buyer_2_income_value_check", nil, self),
Form::Sales::Pages::Buyer2LiveInProperty.new(nil, nil, self),
- Form::Sales::Pages::NumberOfOthersInProperty.new(nil, nil, self),
+ Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property", nil, self, joint_purchase: false),
+ Form::Sales::Pages::NumberOfOthersInProperty.new("number_of_others_in_property_joint_purchase", nil, self, joint_purchase: true),
Form::Sales::Pages::PersonKnown.new("person_2_known", nil, self, person_index: 2),
Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_2_relationship_to_buyer_1", nil, self, person_index: 2),
Form::Sales::Pages::PersonAge.new("person_2_age", nil, self, person_index: 2),
@@ -70,6 +71,14 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection
Form::Sales::Pages::RetirementValueCheck.new("gender_5_retirement_value_check", nil, self, person_index: 5),
Form::Sales::Pages::PersonWorkingSituation.new("person_5_working_situation", nil, self, person_index: 5),
Form::Sales::Pages::RetirementValueCheck.new("working_situation_5_retirement_value_check", nil, self, person_index: 5),
+ Form::Sales::Pages::PersonKnown.new("person_6_known", nil, self, person_index: 6),
+ Form::Sales::Pages::PersonRelationshipToBuyer1.new("person_6_relationship_to_buyer_1", nil, self, person_index: 6),
+ Form::Sales::Pages::PersonAge.new("person_6_age", nil, self, person_index: 6),
+ Form::Sales::Pages::RetirementValueCheck.new("age_6_retirement_value_check", nil, self, person_index: 6),
+ Form::Sales::Pages::PersonGenderIdentity.new("person_6_gender_identity", nil, self, person_index: 6),
+ Form::Sales::Pages::RetirementValueCheck.new("gender_6_retirement_value_check", nil, self, person_index: 6),
+ Form::Sales::Pages::PersonWorkingSituation.new("person_6_working_situation", nil, self, person_index: 6),
+ Form::Sales::Pages::RetirementValueCheck.new("working_situation_6_retirement_value_check", nil, self, person_index: 6),
].flatten.compact
end
diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb
index d9fe89509..6864738cf 100644
--- a/app/models/lettings_log.rb
+++ b/app/models/lettings_log.rb
@@ -65,11 +65,6 @@ class LettingsLog < Log
FormHandler.instance.get_form(form_name) || FormHandler.instance.current_lettings_form
end
- def recalculate_start_year!
- @start_year = nil
- collection_start_year
- end
-
def lettings?
true
end
diff --git a/app/models/log.rb b/app/models/log.rb
index d8aa9e236..505839c69 100644
--- a/app/models/log.rb
+++ b/app/models/log.rb
@@ -39,6 +39,11 @@ class Log < ApplicationRecord
@start_year = startdate < window_end_date ? startdate.year - 1 : startdate.year
end
+ def recalculate_start_year!
+ @start_year = nil
+ collection_start_year
+ end
+
def lettings?
false
end
diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb
index 447f37597..b2c6b08da 100644
--- a/app/models/sales_log.rb
+++ b/app/models/sales_log.rb
@@ -24,6 +24,7 @@ class SalesLog < Log
has_paper_trail
validates_with SalesLogValidator
+ before_validation :recalculate_start_year!, if: :saledate_changed?
before_validation :reset_invalidated_dependent_fields!
before_validation :process_postcode_changes!, if: :postcode_full_changed?
before_validation :process_previous_postcode_changes!, if: :ppostcode_full_changed?
@@ -65,7 +66,20 @@ class SalesLog < Log
end
def optional_fields
- OPTIONAL_FIELDS
+ OPTIONAL_FIELDS + dynamically_not_required
+ end
+
+ def dynamically_not_required
+ not_required = []
+ not_required << "proplen" if proplen_optional?
+
+ not_required
+ end
+
+ def proplen_optional?
+ return false unless collection_start_year
+
+ collection_start_year < 2023
end
def not_started?
diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb
index a5430bbea..6179d05aa 100644
--- a/app/models/validations/financial_validations.rb
+++ b/app/models/validations/financial_validations.rb
@@ -24,11 +24,11 @@ module Validations::FinancialValidations
def validate_net_income(record)
if record.ecstat1 && record.weekly_net_income
if record.weekly_net_income > record.applicable_income_range.hard_max
- record.errors.add :earnings, I18n.t("validations.financial.earnings.over_hard_max", hard_max: record.applicable_income_range.hard_max)
+ record.errors.add :earnings, :over_hard_max, message: I18n.t("validations.financial.earnings.over_hard_max", hard_max: record.applicable_income_range.hard_max)
end
if record.weekly_net_income < record.applicable_income_range.hard_min
- record.errors.add :earnings, I18n.t("validations.financial.earnings.under_hard_min", hard_min: record.applicable_income_range.hard_min)
+ record.errors.add :earnings, :under_hard_min, message: I18n.t("validations.financial.earnings.under_hard_min", hard_min: record.applicable_income_range.hard_min)
end
end
@@ -111,9 +111,11 @@ module Validations::FinancialValidations
def validate_care_home_charges(record)
if record.is_carehome?
period = record.form.get_question("period", record).label_from_value(record.period).downcase
+ # NOTE: This is a temporary change to allow `ccharge` values despite `is_carehome` being true. This value
+ # is going to be moved to a soft validation in CLDC-2074, so we can safely do this.
if record.chcharge.blank?
- record.errors.add :is_carehome, I18n.t("validations.financial.carehome.not_provided", period:)
- record.errors.add :chcharge, I18n.t("validations.financial.carehome.not_provided", period:)
+ # record.errors.add :is_carehome, I18n.t("validations.financial.carehome.not_provided", period:)
+ # record.errors.add :chcharge, I18n.t("validations.financial.carehome.not_provided", period:)
elsif !weekly_value_in_range(record, "chcharge", 10, 1000)
max_chcharge = record.weekly_to_value_per_period(1000)
min_chcharge = record.weekly_to_value_per_period(10)
diff --git a/app/models/validations/household_validations.rb b/app/models/validations/household_validations.rb
index 4ffd0b1f8..afa7867ff 100644
--- a/app/models/validations/household_validations.rb
+++ b/app/models/validations/household_validations.rb
@@ -67,7 +67,7 @@ module Validations::HouseholdValidations
end
if record.age1.present? && record.age1 > 19 && record.previous_tenancy_was_foster_care?
- record.errors.add :prevten, I18n.t("validations.household.prevten.over_20_foster_care")
+ record.errors.add :prevten, :over_20_foster_care, message: I18n.t("validations.household.prevten.over_20_foster_care")
record.errors.add :age1, I18n.t("validations.household.age.lead.over_20")
end
diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb
index c4ce023bb..a1deb94f5 100644
--- a/app/models/validations/sales/sale_information_validations.rb
+++ b/app/models/validations/sales/sale_information_validations.rb
@@ -46,7 +46,7 @@ module Validations::Sales::SaleInformationValidations
def validate_discounted_ownership_value(record)
return unless record.value && record.deposit && record.ownershipsch
- return unless record.mortgage || record.mortgageused == 2
+ return unless record.mortgage || record.mortgageused == 2 || record.mortgageused == 3
return unless record.discount || record.grant || record.type == 29
discount_amount = record.discount ? record.value * record.discount / 100 : 0
diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb
index c1704d948..a44e0a293 100644
--- a/app/models/validations/sales/soft_validations.rb
+++ b/app/models/validations/sales/soft_validations.rb
@@ -60,7 +60,7 @@ module Validations::Sales::SoftValidations
end
def shared_ownership_deposit_invalid?
- return unless mortgage || mortgageused == 2
+ return unless mortgage || mortgageused == 2 || mortgageused == 3
return unless cashdis || !is_type_discount?
return unless deposit && value && equity
diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb
index a215e8f5a..34582091d 100644
--- a/app/services/imports/lettings_logs_import_service.rb
+++ b/app/services/imports/lettings_logs_import_service.rb
@@ -55,6 +55,8 @@ module Imports
}.freeze
def create_log(xml_doc)
+ return if meta_field_value(xml_doc, "form-name").include?("Sales")
+
attributes = {}
previous_status = meta_field_value(xml_doc, "status")
@@ -287,8 +289,38 @@ module Imports
@logs_overridden << lettings_log.old_id
attributes.delete("referral")
save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:earnings, :under_hard_min)
+ @logger.warn("Log #{lettings_log.old_id}: Where the income is 0, set earnings and income to blank and set incref to refused")
+ @logs_overridden << lettings_log.old_id
+
+ attributes.delete("earnings")
+ attributes.delete("incfreq")
+ attributes["incref"] = 1
+ attributes["net_income_known"] = 2
+ save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.include?(:tenancylength) && lettings_log.errors.include?(:tenancy)
+ @logger.warn("Log #{lettings_log.old_id}: Removing tenancylength as invalid")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("tenancylength")
+ attributes.delete("tenancy")
+ save_lettings_log(attributes, previous_status)
+ elsif lettings_log.errors.of_kind?(:prevten, :over_20_foster_care)
+ @logger.warn("Log #{lettings_log.old_id}: Removing age1 and prevten as incompatible")
+ @logs_overridden << lettings_log.old_id
+ attributes.delete("prevten")
+ attributes.delete("age1")
+ save_lettings_log(attributes, previous_status)
else
@logger.error("Log #{lettings_log.old_id}: Failed to import")
+ lettings_log.errors.each do |error|
+ @logger.error("Validation error: Field #{error.attribute}:")
+ @logger.error("\tOwning Organisation: #{lettings_log.owning_organisation&.name}")
+ @logger.error("\tManaging Organisation: #{lettings_log.managing_organisation&.name}")
+ @logger.error("\tOld CORE ID: #{lettings_log.old_id}")
+ @logger.error("\tOld CORE: #{attributes[error.attribute.to_s]&.inspect}")
+ @logger.error("\tNew CORE: #{lettings_log.read_attribute(error.attribute)&.inspect}")
+ @logger.error("\tError message: #{error.type}")
+ end
raise exception
end
end
diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb
index deea3fab6..95af610b6 100644
--- a/app/services/imports/sales_logs_import_service.rb
+++ b/app/services/imports/sales_logs_import_service.rb
@@ -16,6 +16,8 @@ module Imports
private
def create_log(xml_doc)
+ return unless meta_field_value(xml_doc, "form-name").include?("Sales")
+
attributes = {}
previous_status = meta_field_value(xml_doc, "status")
@@ -31,12 +33,14 @@ module Imports
attributes["updated_at"] = Time.zone.parse(meta_field_value(xml_doc, "modified-date"))
attributes["purchid"] = string_or_nil(xml_doc, "PurchaserCode")
attributes["ownershipsch"] = unsafe_string_as_integer(xml_doc, "Ownership")
+ attributes["ownershipsch"] = ownership_from_type(attributes) if attributes["ownershipsch"].blank? # sometimes Ownership is missing, but type is set
attributes["othtype"] = string_or_nil(xml_doc, "Q38OtherSale")
- attributes["jointmore"] = unsafe_string_as_integer(xml_doc, "JointMore")
attributes["jointpur"] = unsafe_string_as_integer(xml_doc, "joint")
+ attributes["jointmore"] = unsafe_string_as_integer(xml_doc, "JointMore") if attributes["jointpur"] == 1
attributes["beds"] = safe_string_as_integer(xml_doc, "Q11Bedrooms")
attributes["companybuy"] = unsafe_string_as_integer(xml_doc, "company") if attributes["ownershipsch"] == 3
- attributes["hhmemb"] = safe_string_as_integer(xml_doc, "HHMEMB")
+ attributes["hholdcount"] = other_household_members(xml_doc, attributes)
+ attributes["hhmemb"] = household_members(xml_doc, attributes)
(1..6).each do |index|
attributes["age#{index}"] = safe_string_as_integer(xml_doc, "P#{index}Age")
attributes["sex#{index}"] = sex(xml_doc, index)
@@ -59,7 +63,6 @@ module Imports
attributes["noint"] = unsafe_string_as_integer(xml_doc, "PartAPurchaser")
attributes["buy2livein"] = unsafe_string_as_integer(xml_doc, "LiveInBuyer2")
attributes["wheel"] = unsafe_string_as_integer(xml_doc, "Q10Wheelchair")
- attributes["hholdcount"] = safe_string_as_integer(xml_doc, "LiveInOther")
attributes["la"] = string_or_nil(xml_doc, "Q14ONSLACode")
attributes["income1"] = safe_string_as_integer(xml_doc, "Q2Person1Income")
attributes["income1nk"] = income_known(unsafe_string_as_integer(xml_doc, "P1IncKnown"))
@@ -102,10 +105,12 @@ module Imports
attributes["previous_la_known"] = nil
attributes["hhregres"] = unsafe_string_as_integer(xml_doc, "ArmedF")
attributes["hhregresstill"] = still_serving(xml_doc)
- attributes["proplen"] = safe_string_as_integer(xml_doc, "Q16aProplen2")
+ attributes["proplen"] = safe_string_as_integer(xml_doc, "Q16aProplen2") || safe_string_as_integer(xml_doc, "Q16aProplensec2")
attributes["mscharge"] = monthly_charges(xml_doc, attributes)
attributes["mscharge_known"] = 1 if attributes["mscharge"].present?
attributes["prevten"] = unsafe_string_as_integer(xml_doc, "Q6PrevTenure")
+ attributes["mortlen"] = mortgage_length(xml_doc, attributes)
+ attributes["extrabor"] = borrowing(xml_doc, attributes)
attributes["mortgageused"] = unsafe_string_as_integer(xml_doc, "MORTGAGEUSED")
attributes["wchair"] = unsafe_string_as_integer(xml_doc, "Q15Wheelchair")
attributes["armedforcesspouse"] = unsafe_string_as_integer(xml_doc, "ARMEDFORCESSPOUSE")
@@ -117,11 +122,6 @@ module Imports
attributes["socprevten"] = unsafe_string_as_integer(xml_doc, "PrevRentType")
attributes["mortgagelender"] = mortgage_lender(xml_doc, attributes)
attributes["mortgagelenderother"] = mortgage_lender_other(xml_doc, attributes)
- attributes["mortlen"] = mortgage_length(xml_doc, attributes)
- attributes["extrabor"] = borrowing(xml_doc, attributes)
- attributes["totadult"] = safe_string_as_integer(xml_doc, "TOTADULT") # would get overridden
- attributes["totchild"] = safe_string_as_integer(xml_doc, "TOTCHILD") # would get overridden
- attributes["hhtype"] = unsafe_string_as_integer(xml_doc, "HHTYPE")
attributes["pcode1"] = string_or_nil(xml_doc, "PCODE1")
attributes["pcode2"] = string_or_nil(xml_doc, "PCODE2")
attributes["postcode_full"] = compose_postcode(xml_doc, "PCODE1", "PCODE2")
@@ -396,6 +396,49 @@ module Imports
end
end
+ def ownership_from_type(attributes)
+ case attributes["type"]
+ when 2, 24, 18, 16, 28, 31, 30
+ 1 # shared ownership
+ when 8, 14, 27, 9, 29, 21, 22
+ 2 # discounted ownership
+ when 10, 12
+ 3 # outright sale
+ end
+ end
+
+ def other_household_members(xml_doc, attributes)
+ hholdcount = safe_string_as_integer(xml_doc, "LiveInOther")
+ return hholdcount if hholdcount.present?
+
+ other_people_with_details(xml_doc, attributes)
+ end
+
+ def other_people_with_details(xml_doc, attributes)
+ number_of_buyers = attributes["jointpur"] == 1 ? 2 : 1
+ highest_person_index_with_details = number_of_buyers
+
+ (2..6).each do |person_index|
+ age = string_or_nil(xml_doc, "P#{person_index}Age")
+ gender = string_or_nil(xml_doc, "P#{person_index}Sex")
+ relationship = string_or_nil(xml_doc, "P#{person_index}Rel")
+ economic_status = string_or_nil(xml_doc, "P#{person_index}Eco")
+ if gender.present? || age.present? || relationship.present? || economic_status.present?
+ highest_person_index_with_details = person_index
+ end
+ end
+
+ highest_person_index_with_details - number_of_buyers
+ end
+
+ def household_members(_xml_doc, attributes)
+ if attributes["jointpur"] == 2
+ attributes["hholdcount"] + 1
+ else
+ attributes["hholdcount"] + 2
+ end
+ end
+
def set_default_values(attributes)
attributes["armedforcesspouse"] ||= 7
attributes["hhregres"] ||= 8
@@ -404,7 +447,11 @@ module Imports
attributes["hb"] ||= 4
attributes["prevown"] ||= 3
attributes["savingsnk"] ||= attributes["savings"].present? ? 0 : 1
- # attributes["noint"] = 1 # not interviewed
+ attributes["jointmore"] ||= 3 if attributes["jointpur"] == 1
+ attributes["inc1mort"] ||= 3
+ if [attributes["pregyrha"], attributes["pregla"], attributes["pregghb"], attributes["pregother"]].all?(&:blank?)
+ attributes["pregblank"] = 1
+ end
# buyer 1 characteristics
attributes["age1_known"] ||= 1
@@ -414,7 +461,6 @@ module Imports
attributes["national"] ||= 13
attributes["ecstat1"] ||= 10
attributes["income1nk"] ||= attributes["income1"].present? ? 0 : 1
- attributes["hholdcount"] ||= default_household_count(attributes) # just for testing, might need to change
# buyer 2 characteristics
if attributes["jointpur"] == 1
@@ -422,6 +468,9 @@ module Imports
attributes["sex2"] ||= "R"
attributes["ecstat2"] ||= 10
attributes["income2nk"] ||= attributes["income2"].present? ? 0 : 1
+ attributes["relat2"] ||= "R"
+ attributes["inc2mort"] ||= 3
+ attributes["buy2livein"] ||= 1 unless attributes["ownershipsch"] == 3
end
# other household members characteristics
@@ -434,15 +483,8 @@ module Imports
end
def missing_answers(sales_log)
- applicable_questions = sales_log.form.subsections.map { |s| s.applicable_questions(sales_log) }.flatten
+ applicable_questions = sales_log.form.subsections.map { |s| s.applicable_questions(sales_log).select { |q| q.enabled?(sales_log) } }.flatten
applicable_questions.filter { |q| q.unanswered?(sales_log) }.map(&:id)
end
-
- # just for testing, logic might need to change
- def default_household_count(attributes)
- return 0 if attributes["hhmemb"].zero? || attributes["hhmemb"].blank?
-
- attributes["jointpur"] == 1 ? attributes["hhmemb"] - 2 : attributes["hhmemb"] - 1
- end
end
end
diff --git a/app/views/bulk_upload_lettings_results/show.html.erb b/app/views/bulk_upload_lettings_results/show.html.erb
index 84374e26a..9a8ccddec 100644
--- a/app/views/bulk_upload_lettings_results/show.html.erb
+++ b/app/views/bulk_upload_lettings_results/show.html.erb
@@ -1,5 +1,7 @@
-<% content_for :before_content do %>
- <%= govuk_back_link(text: "Back", href: summary_bulk_upload_lettings_result_path(@bulk_upload)) %>
+<% if BulkUploadErrorSummaryTableComponent.new(bulk_upload: @bulk_upload).errors? %>
+ <% content_for :before_content do %>
+ <%= govuk_back_link(text: "Back", href: summary_bulk_upload_lettings_result_path(@bulk_upload)) %>
+ <% end %>
<% end %>
@@ -22,3 +24,5 @@
<% end %>
+
+<%= govuk_button_link_to "Upload your file again", start_bulk_upload_lettings_logs_path %>
diff --git a/app/views/form/headers/_person_6_known_page.erb b/app/views/form/headers/_person_6_known_page.erb
new file mode 100644
index 000000000..96cc94fd3
--- /dev/null
+++ b/app/views/form/headers/_person_6_known_page.erb
@@ -0,0 +1 @@
+You have given us the details for <%= log.joint_purchase? ? 3 : 4 %> of the <%= log.hholdcount %> other people in the household
diff --git a/config/sale_range_data/2023.csv b/config/sale_range_data/2023.csv
index ebe873c07..0106122d8 100644
--- a/config/sale_range_data/2023.csv
+++ b/config/sale_range_data/2023.csv
@@ -87,10 +87,10 @@ Boston,E07000136,1,58000,258000
Boston,E07000136,2,58000,258000
Boston,E07000136,3,111000,308000
Boston,E07000136,4,212000,510000
-Bournemouth, Christchurch and Poole,E06000058,1,140000,500000
-Bournemouth, Christchurch and Poole,E06000058,2,197000,500000
-Bournemouth, Christchurch and Poole,E06000058,3,285000,657000
-Bournemouth, Christchurch and Poole,E06000058,4,370000,1321000
+"Bournemouth, Christchurch and Poole",E06000058,1,140000,500000
+"Bournemouth, Christchurch and Poole",E06000058,2,197000,500000
+"Bournemouth, Christchurch and Poole",E06000058,3,285000,657000
+"Bournemouth, Christchurch and Poole",E06000058,4,370000,1321000
Bracknell Forest,E06000036,1,95000,488000
Bracknell Forest,E06000036,2,157000,488000
Bracknell Forest,E06000036,3,341000,654000
@@ -119,10 +119,10 @@ Brighton and Hove,E06000043,1,185000,526000
Brighton and Hove,E06000043,2,270000,610000
Brighton and Hove,E06000043,3,350000,846000
Brighton and Hove,E06000043,4,458000,1487000
-Bristol, City of,E06000023,1,145000,417000
-Bristol, City of,E06000023,2,184000,562000
-Bristol, City of,E06000023,3,242000,685000
-Bristol, City of,E06000023,4,331000,1394000
+"Bristol, City of",E06000023,1,145000,417000
+"Bristol, City of",E06000023,2,184000,562000
+"Bristol, City of",E06000023,3,242000,685000
+"Bristol, City of",E06000023,4,331000,1394000
Broadland,E07000144,1,126000,334000
Broadland,E07000144,2,140000,334000
Broadland,E07000144,3,225000,433000
@@ -459,10 +459,10 @@ Havering,E09000016,1,137000,472000
Havering,E09000016,2,204000,481000
Havering,E09000016,3,336000,657000
Havering,E09000016,4,412000,1232000
-Herefordshire, County of,E06000019,1,98000,419000
-Herefordshire, County of,E06000019,2,105000,419000
-Herefordshire, County of,E06000019,3,162000,499000
-Herefordshire, County of,E06000019,4,283000,885000
+"Herefordshire, County of",E06000019,1,98000,419000
+"Herefordshire, County of",E06000019,2,105000,419000
+"Herefordshire, County of",E06000019,3,162000,499000
+"Herefordshire, County of",E06000019,4,283000,885000
Hertsmere,E07000098,1,178000,666000
Hertsmere,E07000098,2,316000,666000
Hertsmere,E07000098,3,440000,918000
@@ -515,10 +515,10 @@ King's Lynn and West Norfolk,E07000146,1,77000,346000
King's Lynn and West Norfolk,E07000146,2,123000,346000
King's Lynn and West Norfolk,E07000146,3,161000,408000
King's Lynn and West Norfolk,E07000146,4,243000,778000
-Kingston upon Hull, City of,E06000010,1,63000,189000
-Kingston upon Hull, City of,E06000010,2,67000,189000
-Kingston upon Hull, City of,E06000010,3,84000,259000
-Kingston upon Hull, City of,E06000010,4,110000,415000
+"Kingston upon Hull, City of",E06000010,1,63000,189000
+"Kingston upon Hull, City of",E06000010,2,67000,189000
+"Kingston upon Hull, City of",E06000010,3,84000,259000
+"Kingston upon Hull, City of",E06000010,4,110000,415000
Kingston upon Thames,E09000021,1,156000,649000
Kingston upon Thames,E09000021,2,325000,708000
Kingston upon Thames,E09000021,3,398000,935000
diff --git a/db/migrate/20230301144555_add_pregblank.rb b/db/migrate/20230301144555_add_pregblank.rb
new file mode 100644
index 000000000..308ca5e10
--- /dev/null
+++ b/db/migrate/20230301144555_add_pregblank.rb
@@ -0,0 +1,5 @@
+class AddPregblank < ActiveRecord::Migration[7.0]
+ def change
+ add_column :sales_logs, :pregblank, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index c21ee4a8e..afa0b6b74 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_02_15_112932) do
+ActiveRecord::Schema[7.0].define(version: 2023_03_01_144555) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -522,15 +522,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_15_112932) do
t.integer "income2_value_check"
t.integer "monthly_charges_value_check"
t.integer "value_value_check"
- t.integer "saledate_check"
t.integer "details_known_5"
t.integer "details_known_6"
+ t.integer "saledate_check"
+ t.integer "prevshared"
+ t.integer "staircasesale"
t.integer "ethnic_group2"
t.integer "ethnicbuy2"
t.integer "proplen_asked"
- t.integer "prevshared"
- t.integer "staircasesale"
t.string "old_id"
+ t.integer "pregblank"
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["old_id"], name: "index_sales_logs_on_old_id", unique: true
diff --git a/db/seeds.rb b/db/seeds.rb
index 10823c62d..341677b27 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -324,6 +324,5 @@ unless Rails.env.test?
service.call
end
end
- puts LaSaleRange.count
end
# rubocop:enable Rails/Output
diff --git a/lib/tasks/full_import.rake b/lib/tasks/full_import.rake
index e141b6520..35943db2d 100644
--- a/lib/tasks/full_import.rake
+++ b/lib/tasks/full_import.rake
@@ -18,6 +18,7 @@ namespace :core do
Import.new(Imports::DataProtectionConfirmationImportService, :create_data_protection_confirmations, "dataprotect"),
Import.new(Imports::OrganisationRentPeriodImportService, :create_organisation_rent_periods, "rent-period"),
Import.new(Imports::LettingsLogsImportService, :create_logs, "logs"),
+ # Import.new(Imports::SalesLogsImportService, :create_logs, "logs"),
]
import_list.each do |step|
diff --git a/spec/components/bulk_upload_error_summary_table_component_spec.rb b/spec/components/bulk_upload_error_summary_table_component_spec.rb
index cdb0b58bf..a7468d70a 100644
--- a/spec/components/bulk_upload_error_summary_table_component_spec.rb
+++ b/spec/components/bulk_upload_error_summary_table_component_spec.rb
@@ -5,6 +5,10 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do
let(:bulk_upload) { create(:bulk_upload) }
+ before do
+ stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 0)
+ end
+
context "when no errors" do
it "does not renders any rows" do
result = render_inline(component)
@@ -12,6 +16,19 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do
end
end
+ context "when below threshold" do
+ before do
+ stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 16)
+
+ create(:bulk_upload_error, bulk_upload:, col: "A", row: 1)
+ end
+
+ it "does not render rows" do
+ result = render_inline(component)
+ expect(result).to have_selector("tbody tr", count: 0)
+ end
+ end
+
context "when there are 2 independent errors" do
let!(:error_2) { create(:bulk_upload_error, bulk_upload:, col: "B", row: 2) }
let!(:error_1) { create(:bulk_upload_error, bulk_upload:, col: "A", row: 1) }
@@ -78,4 +95,22 @@ RSpec.describe BulkUploadErrorSummaryTableComponent, type: :component do
])
end
end
+
+ describe "#errors?" do
+ context "when there are no errors" do
+ it "returns false" do
+ expect(component).not_to be_errors
+ end
+ end
+
+ context "when there are errors" do
+ before do
+ create(:bulk_upload_error, bulk_upload:, col: "A", row: 2, field: "field_1")
+ end
+
+ it "returns true" do
+ expect(component).to be_errors
+ end
+ end
+ end
end
diff --git a/spec/fixtures/imports/logs/shared_ownership_sales_log.xml b/spec/fixtures/imports/logs/shared_ownership_sales_log.xml
new file mode 100644
index 000000000..6e0c11174
--- /dev/null
+++ b/spec/fixtures/imports/logs/shared_ownership_sales_log.xml
@@ -0,0 +1,333 @@
+
+
+ 2022-CORE-Sales
+ shared_ownership_sales_log
+ c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa
+ 7c5bd5fb549c09a2c55d7cb90d7ba84927e64618
+ 7c5bd5fb549c09a2c55d7cb90d7ba84927e64618
+ 2023-02-21T11:48:28.255968Z
+ 2023-02-22T11:00:06.575832Z
+ submitted-valid
+ 2022
+ Manual Entry
+
+
+
+
+ Yes
+ 2023-01-17
+ Shared ownership example
+ 1 Yes - a shared ownership scheme
+ 2 Shared Ownership
+
+
+
+ 2 No
+ 1 Yes
+ 2 No
+
+ 2 Yes
+
+
+ 2
+ 1 Flat or maisonette
+ 1 Purpose built
+ SW1A 1AA
+ Westminster
+ E09000033
+ 3 Don’t know
+
+
+ 30
+ Male
+ 1 Full Time - 30 hours or more a week
+ 2 White: Irish
+ 18 United Kingdom
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1 Yes
+
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 76000
+ 1
+ 47000
+ 0
+ 235000
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 0
+ 0
+ 1
+ 1
+ 2
+ 3
+ 17
+ 1
+ 2023
+ 6
+ 9
+ 2022
+ 8
+ 1
+ 2023
+ SW14
+ 7QP
+ SW1A
+ 1AA
+
+
+
+ 2 Private registered provider (PRP) or housing association tenant
+ SW14 7QP
+
+ Richmond-upon-Thames
+ E09000027
+ Yes
+
+
+
+
+
+
+ 8 Don’t know
+
+
+ 2 No
+ 2 No
+
+
+ 1 Yes
+ 47000
+ 1 Yes
+
+
+
+ 4 Don’t know
+ 1 Yes
+ 89000
+ 1 Yes
+
+
+
+
+ 1
+ 2 No
+
+ 30
+ 2 No
+ 2023-01-08
+ 2022-09-06
+ 2 No
+
+
+
+ 550000
+ 30
+ 1 Yes
+ 76000
+ Nationwide
+ 33
+ 2 No
+ 89000
+
+ 912.00
+ 134.24
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 0
+
+
+ 3 = 1 adult
+
+
+ 2 Shared Ownership
+
+
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 1
+
+
+
+
+ E12000007
+ 1
+ 1 Test
+ 655
+
+
diff --git a/spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml b/spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml
index bc1d5f274..b697c4960 100644
--- a/spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml
+++ b/spec/fixtures/imports/sales_logs/discounted_ownership_sales_log.xml
@@ -292,7 +292,7 @@
- 0
+ 1
0
0
diff --git a/spec/fixtures/imports/sales_logs/lettings_log.xml b/spec/fixtures/imports/sales_logs/lettings_log.xml
new file mode 100644
index 000000000..1f7f794f6
--- /dev/null
+++ b/spec/fixtures/imports/sales_logs/lettings_log.xml
@@ -0,0 +1,524 @@
+
+
+ 2021-CORE-SR-SH
+ lettings_log
+ c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa
+ 7c5bd5fb549c09z2c55d9cb90d7ba84927e64618
+ 7c5bd5fb549c09z2c55d9cb90d7ba84927e64618
+ 2022-01-05T12:50:20.39153Z
+ 2022-01-05T12:50:20.39153Z
+ submitted-valid
+ 2021
+ Manual Entry
+
+
+
+
+ Yes
+ 2021-11-05
+
+ 2 Local Authority
+
+ <_1cmangroupcode>0123
+ <_1cschemecode>10
+
+ 3 No
+
+
+
+ <_2a>2 No
+ 1 Secure (inc flexible)
+
+ <_2bTenCode>14044912001
+ <_2cYears>2
+
+
+ 72
+
+ Female
+ 5) Retired
+ 1 White: English/Scottish/Welsh/Northern Irish/British
+ 1 UK national resident in UK
+ 74
+
+ Male
+ Partner
+ 5) Retired
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2 No
+
+
+ 2 No
+
+
+ 9 Not in receipt of either UC or HB
+
+
+ 2 Some
+ Refused
+
+
+
+
+ 13 Property unsuitable because of ill health / disability
+
+
+
+ <_9b override-field="">2 No
+
+
+
+
+ Yes
+
+ 1 Yes
+
+
+ Yes
+
+
+
+
+
+
+
+ 26 Owner occupation (private)
+ DLUHC
+ E08000035
+ S80 4DJ
+
+ 5 5 years or more
+ 9 3 years but under 4 years
+
+
+ 1 Not homeless
+ 2 No
+
+
+
+
+
+
+
+ 1 Yes
+ 1 Yes
+ 1 Yes
+
+
+ 2 Tenant applied direct (no referral or nomination)
+
+
+
+ 7 Weekly for 48 weeks
+ 125.00
+
+
+ 7.00
+ 132.00
+
+
+
+
+ 2021-08-24
+
+
+ 0
+ 14044912
+
+
+ 1 Yes
+ 15 First let of newbuild property
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ <_100>0
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ <_70>1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 1
+ 1
+ 2
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2
+ 74
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 74
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 72
+ 0
+ 74
+ 2022-01-05Z
+ 2022-01-20Z
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 0
+ 0
+ 20
+ 0
+ 20
+ A
+ 1
+ 1
+ 1
+ 1
+ 4
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+ 0.00
+ 2
+ 1 New Tenant
+
+ 73
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 2
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+ 0
+ 0
+ 1
+ 2 = 2 Adults at least one is an Elder
+
+
+ 15.00
+
+
+ 2 Local Authority
+
+
+ E12000004
+ 1
+ DLUHC
+ DLUHC
+ N/A
+ N/A
+
+ 2
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 15
+ 15
+ 000001005048
+ D
+ 15
+ 6
+ 7
+ 1
+ 2
+ A
+ P
+ M
+
+ DLUHC
+ E08000035
+ S80 4QE
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+
+
+
+
+ 115.38
+ 121.85
+
+
+ 6.46
+
+ 115.38
+ 121.85
+
+
+ 6.46
+
+
+ 1
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 1
+
+ 115.38
+ 0
+
+ 0
+ 117.4
+ 10
+
+
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 0
+ 5
+ 11
+ 2021
+ 24
+ 8
+ 2021
+
+
+
+ LS16
+ 6FT
+ LS16
+ 6FT
+
+
diff --git a/spec/lib/tasks/full_import_spec.rb b/spec/lib/tasks/full_import_spec.rb
index a735db40d..67e8ca715 100644
--- a/spec/lib/tasks/full_import_spec.rb
+++ b/spec/lib/tasks/full_import_spec.rb
@@ -22,6 +22,7 @@ describe "rake core:full_import", type: :task do
context "when starting a full import" do
let(:lettings_logs_service) { instance_double(Imports::LettingsLogsImportService) }
+ let(:sales_logs_service) { instance_double(Imports::SalesLogsImportService) }
let(:rent_period_service) { instance_double(Imports::OrganisationRentPeriodImportService) }
let(:data_protection_service) { instance_double(Imports::DataProtectionConfirmationImportService) }
let(:user_service) { instance_double(Imports::UserImportService) }
@@ -37,6 +38,7 @@ describe "rake core:full_import", type: :task do
allow(Imports::DataProtectionConfirmationImportService).to receive(:new).and_return(data_protection_service)
allow(Imports::OrganisationRentPeriodImportService).to receive(:new).and_return(rent_period_service)
allow(Imports::LettingsLogsImportService).to receive(:new).and_return(lettings_logs_service)
+ allow(Imports::SalesLogsImportService).to receive(:new).and_return(sales_logs_service)
end
it "raises an exception if no parameters are provided" do
@@ -54,6 +56,7 @@ describe "rake core:full_import", type: :task do
expect(data_protection_service).to receive(:create_data_protection_confirmations).with("dataprotect")
expect(rent_period_service).to receive(:create_organisation_rent_periods).with("rent-period")
expect(lettings_logs_service).to receive(:create_logs).with("logs")
+ # expect(sales_logs_service).to receive(:create_logs).with("logs")
task.invoke(fixture_path)
end
@@ -73,6 +76,7 @@ describe "rake core:full_import", type: :task do
expect(data_protection_service).to receive(:create_data_protection_confirmations)
expect(rent_period_service).to receive(:create_organisation_rent_periods)
expect(lettings_logs_service).to receive(:create_logs)
+ # expect(sales_logs_service).to receive(:create_logs)
expect(scheme_service).not_to receive(:create_schemes)
expect(location_service).not_to receive(:create_scheme_locations)
diff --git a/spec/mailers/bulk_upload_mailer_spec.rb b/spec/mailers/bulk_upload_mailer_spec.rb
index d0217bfaf..a0042cf69 100644
--- a/spec/mailers/bulk_upload_mailer_spec.rb
+++ b/spec/mailers/bulk_upload_mailer_spec.rb
@@ -93,7 +93,7 @@ RSpec.describe BulkUploadMailer do
year_combo: bulk_upload.year_combo,
lettings_or_sales: bulk_upload.log_type,
error_description: "We noticed that you have a lot of similar errors in column A, B. Please correct your data export and upload again.",
- summary_report_link: "http://localhost:3000/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary",
+ summary_report_link: "http://localhost:3000/lettings-logs/bulk-upload-results/#{bulk_upload.id}",
},
)
@@ -103,6 +103,8 @@ RSpec.describe BulkUploadMailer do
context "when 4 columns with errors" do
before do
+ stub_const("BulkUploadErrorSummaryTableComponent::DISPLAY_THRESHOLD", 0)
+
create(:bulk_upload_error, bulk_upload:, col: "A")
create(:bulk_upload_error, bulk_upload:, col: "B")
create(:bulk_upload_error, bulk_upload:, col: "C")
diff --git a/spec/models/form/sales/pages/buyer1_previous_tenure_spec.rb b/spec/models/form/sales/pages/buyer1_previous_tenure_spec.rb
index e38f287f5..a67fa3e16 100644
--- a/spec/models/form/sales/pages/buyer1_previous_tenure_spec.rb
+++ b/spec/models/form/sales/pages/buyer1_previous_tenure_spec.rb
@@ -1,10 +1,8 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Buyer1PreviousTenure, type: :model do
- subject(:page) { described_class.new(page_id, page_definition, subsection) }
+ subject(:page) { described_class.new(nil, nil, subsection) }
- let(:page_id) { nil }
- let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
diff --git a/spec/models/form/sales/pages/number_of_others_in_property_spec.rb b/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
index c2efdcb21..3503a1b9f 100644
--- a/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
+++ b/spec/models/form/sales/pages/number_of_others_in_property_spec.rb
@@ -1,10 +1,11 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::NumberOfOthersInProperty, type: :model do
- subject(:page) { described_class.new(page_id, page_definition, subsection) }
+ subject(:page) { described_class.new(page_id, page_definition, subsection, joint_purchase:) }
- let(:page_id) { nil }
+ let(:page_id) { "number_of_others_in_property" }
let(:page_definition) { nil }
+ let(:joint_purchase) { false }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
@@ -26,4 +27,39 @@ RSpec.describe Form::Sales::Pages::NumberOfOthersInProperty, type: :model do
it "has the correct description" do
expect(page.description).to be_nil
end
+
+ it "has the correct depends_on" do
+ expect(page.depends_on).to eq([
+ {
+ "privacynotice" => 1,
+ "jointpur" => 2,
+ },
+ {
+ "noint" => 1,
+ "jointpur" => 2,
+ },
+ ])
+ end
+
+ context "with joint purchase" do
+ let(:page_id) { "number_of_others_in_property_joint_purchase" }
+ let(:joint_purchase) { true }
+
+ it "has the correct id" do
+ expect(page.id).to eq("number_of_others_in_property_joint_purchase")
+ end
+
+ it "has the correct depends_on" do
+ expect(page.depends_on).to eq([
+ {
+ "privacynotice" => 1,
+ "jointpur" => 1,
+ },
+ {
+ "noint" => 1,
+ "jointpur" => 1,
+ },
+ ])
+ end
+ end
end
diff --git a/spec/models/form/sales/pages/shared_ownership_type_spec.rb b/spec/models/form/sales/pages/shared_ownership_type_spec.rb
index b8b71080f..09c277766 100644
--- a/spec/models/form/sales/pages/shared_ownership_type_spec.rb
+++ b/spec/models/form/sales/pages/shared_ownership_type_spec.rb
@@ -5,7 +5,9 @@ RSpec.describe Form::Sales::Pages::SharedOwnershipType, type: :model do
let(:page_id) { nil }
let(:page_definition) { nil }
- let(:subsection) { instance_double(Form::Subsection) }
+ let(:start_date) { Time.utc(2022, 4, 1) }
+ let(:form) { instance_double(Form, start_date:) }
+ let(:subsection) { instance_double(Form::Subsection, form:) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
diff --git a/spec/models/form/sales/questions/buyer1_mortgage_spec.rb b/spec/models/form/sales/questions/buyer1_mortgage_spec.rb
index 59ae45afc..df47cd1ce 100644
--- a/spec/models/form/sales/questions/buyer1_mortgage_spec.rb
+++ b/spec/models/form/sales/questions/buyer1_mortgage_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Form::Sales::Questions::Buyer1Mortgage, type: :model do
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
+ let(:log) { create(:sales_log) }
it "has correct page" do
expect(question.page).to eq(page)
@@ -16,11 +17,11 @@ RSpec.describe Form::Sales::Questions::Buyer1Mortgage, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("Was buyer 1's income used for a mortgage application?")
+ expect(question.header).to eq("Was buyer 1’s income used for a mortgage application?")
end
it "has the correct check_answer_label" do
- expect(question.check_answer_label).to eq("Buyer 1's income used for mortgage application")
+ expect(question.check_answer_label).to eq("Buyer 1’s income used for mortgage application")
end
it "has the correct type" do
@@ -35,6 +36,14 @@ RSpec.describe Form::Sales::Questions::Buyer1Mortgage, type: :model do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
+ })
+ end
+
+ it "has the correct displayed_answer_options" do
+ expect(question.displayed_answer_options(log)).to eq({
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
})
end
diff --git a/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb b/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb
index ae1da940a..4321700b4 100644
--- a/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb
+++ b/spec/models/form/sales/questions/buyer1_previous_tenure_spec.rb
@@ -1,11 +1,10 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::Buyer1PreviousTenure, type: :model do
- subject(:question) { described_class.new(question_id, question_definition, page) }
+ subject(:question) { described_class.new(nil, nil, page) }
- let(:question_id) { nil }
- let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
+ let(:log) { create(:sales_log) }
it "has correct page" do
expect(question.page).to eq(page)
@@ -16,11 +15,11 @@ RSpec.describe Form::Sales::Questions::Buyer1PreviousTenure, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("What was buyer 1's previous tenure?")
+ expect(question.header).to eq("What was buyer 1’s previous tenure?")
end
it "has the correct check_answer_label" do
- expect(question.check_answer_label).to eq("Buyer 1's previous tenure")
+ expect(question.check_answer_label).to eq("Buyer 1’s previous tenure")
end
it "has the correct type" do
@@ -41,6 +40,7 @@ RSpec.describe Form::Sales::Questions::Buyer1PreviousTenure, type: :model do
"6" => { "value" => "Living with family or friends" },
"7" => { "value" => "Temporary accomodation" },
"9" => { "value" => "Other" },
+ "0" => { "value" => "Don’t know" },
})
end
end
diff --git a/spec/models/form/sales/questions/buyer2_mortgage_spec.rb b/spec/models/form/sales/questions/buyer2_mortgage_spec.rb
index bb561af43..5bf83a2d0 100644
--- a/spec/models/form/sales/questions/buyer2_mortgage_spec.rb
+++ b/spec/models/form/sales/questions/buyer2_mortgage_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Form::Sales::Questions::Buyer2Mortgage, type: :model do
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
+ let(:log) { create(:sales_log) }
it "has correct page" do
expect(question.page).to eq(page)
@@ -16,11 +17,11 @@ RSpec.describe Form::Sales::Questions::Buyer2Mortgage, type: :model do
end
it "has the correct header" do
- expect(question.header).to eq("Was buyer 2's income used for a mortgage application?")
+ expect(question.header).to eq("Was buyer 2’s income used for a mortgage application?")
end
it "has the correct check_answer_label" do
- expect(question.check_answer_label).to eq("Buyer 2's income used for mortgage application")
+ expect(question.check_answer_label).to eq("Buyer 2’s income used for mortgage application")
end
it "has the correct type" do
@@ -35,6 +36,14 @@ RSpec.describe Form::Sales::Questions::Buyer2Mortgage, type: :model do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
+ })
+ end
+
+ it "has the correct displayed_answer_options" do
+ expect(question.displayed_answer_options(log)).to eq({
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
})
end
diff --git a/spec/models/form/sales/questions/buyers_organisations_spec.rb b/spec/models/form/sales/questions/buyers_organisations_spec.rb
index d9f61df5f..88af9917d 100644
--- a/spec/models/form/sales/questions/buyers_organisations_spec.rb
+++ b/spec/models/form/sales/questions/buyers_organisations_spec.rb
@@ -41,6 +41,18 @@ RSpec.describe Form::Sales::Questions::BuyersOrganisations, type: :model do
it "has the correct answer_options" do
expect(question.answer_options).to eq(
+ {
+ "pregyrha" => { "value" => "Their private registered provider (PRP) - housing association" },
+ "pregother" => { "value" => "Other private registered provider (PRP) - housing association" },
+ "pregla" => { "value" => "Local Authority" },
+ "pregghb" => { "value" => "Help to Buy Agent" },
+ "pregblank" => { "value" => "None of the above" },
+ },
+ )
+ end
+
+ it "has the correct displayed_answer_options" do
+ expect(question.displayed_answer_options(FactoryBot.create(:sales_log))).to eq(
{
"pregyrha" => { "value" => "Their private registered provider (PRP) - housing association" },
"pregother" => { "value" => "Other private registered provider (PRP) - housing association" },
diff --git a/spec/models/form/sales/questions/mortgageused_spec.rb b/spec/models/form/sales/questions/mortgageused_spec.rb
index e958de8ea..a31f063c9 100644
--- a/spec/models/form/sales/questions/mortgageused_spec.rb
+++ b/spec/models/form/sales/questions/mortgageused_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Form::Sales::Questions::Mortgageused, type: :model do
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
+ let(:log) { create(:sales_log) }
it "has correct page" do
expect(question.page).to eq(page)
@@ -35,6 +36,7 @@ RSpec.describe Form::Sales::Questions::Mortgageused, type: :model do
expect(question.answer_options).to eq({
"1" => { "value" => "Yes" },
"2" => { "value" => "No" },
+ "3" => { "value" => "Don’t know" },
})
end
@@ -45,4 +47,11 @@ RSpec.describe Form::Sales::Questions::Mortgageused, type: :model do
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
+
+ it "has the correct displayed_answer_options" do
+ expect(question.displayed_answer_options(log)).to eq({
+ "1" => { "value" => "Yes" },
+ "2" => { "value" => "No" },
+ })
+ end
end
diff --git a/spec/models/form/sales/questions/number_of_others_in_property_spec.rb b/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
index 81c49770a..2bb50f80b 100644
--- a/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
+++ b/spec/models/form/sales/questions/number_of_others_in_property_spec.rb
@@ -1,11 +1,12 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
- subject(:question) { described_class.new(question_id, question_definition, page) }
+ subject(:question) { described_class.new(question_id, question_definition, page, joint_purchase:) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
+ let(:joint_purchase) { true }
it "has correct page" do
expect(question.page).to eq(page)
@@ -32,6 +33,26 @@ RSpec.describe Form::Sales::Questions::NumberOfOthersInProperty, type: :model do
end
it "has the correct hint" do
- expect(question.hint_text).to eq("You can provide details for a maximum of 4 other people.")
+ expect(question.hint_text).to eq("You can provide details for a maximum of 4 other people for a joint purchase.")
+ end
+
+ it "has the correct min" do
+ expect(question.min).to eq(0)
+ end
+
+ it "has the correct max" do
+ expect(question.max).to eq(4)
+ end
+
+ context "with non joint purchase" do
+ let(:joint_purchase) { false }
+
+ it "has the correct hint" do
+ expect(question.hint_text).to eq("You can provide details for a maximum of 5 other people if there is only one buyer.")
+ end
+
+ it "has the correct max" do
+ expect(question.max).to eq(5)
+ end
end
end
diff --git a/spec/models/form/sales/questions/shared_ownership_type_spec.rb b/spec/models/form/sales/questions/shared_ownership_type_spec.rb
index c164c5794..3f60155bf 100644
--- a/spec/models/form/sales/questions/shared_ownership_type_spec.rb
+++ b/spec/models/form/sales/questions/shared_ownership_type_spec.rb
@@ -5,7 +5,10 @@ RSpec.describe Form::Sales::Questions::SharedOwnershipType, type: :model do
let(:question_id) { nil }
let(:question_definition) { nil }
- let(:page) { instance_double(Form::Page) }
+ let(:start_date) { Time.utc(2022, 4, 1) }
+ let(:form) { instance_double(Form, start_date:) }
+ let(:subsection) { instance_double(Form::Subsection, form:) }
+ let(:page) { instance_double(Form::Page, subsection:) }
it "has correct page" do
expect(question.page).to eq(page)
@@ -35,15 +38,34 @@ RSpec.describe Form::Sales::Questions::SharedOwnershipType, type: :model do
expect(question.hint_text).to eq("A shared ownership sale is when the purchaser buys up to 75% of the property value and pays rent to the Private Registered Provider (PRP) on the remaining portion")
end
- it "has the correct answer_options" do
- expect(question.answer_options).to eq({
- "2" => { "value" => "Shared Ownership" },
- "24" => { "value" => "Old Persons Shared Ownership" },
- "18" => { "value" => "Social HomeBuy (shared ownership purchase)" },
- "16" => { "value" => "Home Ownership for people with Long Term Disabilities (HOLD)" },
- "28" => { "value" => "Rent to Buy - Shared Ownership" },
- "31" => { "value" => "Right to Shared Ownership" },
- "30" => { "value" => "Shared Ownership - 2021 model lease" },
- })
+ context "when form start date is 2022" do
+ it "has the correct answer_options" do
+ expect(question.answer_options).to eq({
+ "2" => { "value" => "Shared Ownership" },
+ "24" => { "value" => "Old Persons Shared Ownership" },
+ "18" => { "value" => "Social HomeBuy (shared ownership purchase)" },
+ "16" => { "value" => "Home Ownership for people with Long-Term Disabilities (HOLD)" },
+ "28" => { "value" => "Rent to Buy - Shared Ownership" },
+ "31" => { "value" => "Right to Shared Ownership" },
+ "30" => { "value" => "Shared Ownership - 2021 model lease" },
+ })
+ end
+ end
+
+ context "when form start date is 2023" do
+ let(:start_date) { Time.utc(2023, 4, 2) }
+
+ it "has the correct answer_options" do
+ expect(question.answer_options).to eq({
+ "2" => { "value" => "Shared Ownership (old model lease)" },
+ "30" => { "value" => "Shared Ownership (new model lease)" },
+ "18" => { "value" => "Social HomeBuy — shared ownership purchase" },
+ "16" => { "value" => "Home Ownership for people with Long-Term Disabilities (HOLD)" },
+ "24" => { "value" => "Older Persons Shared Ownership" },
+ "28" => { "value" => "Rent to Buy — Shared Ownership" },
+ "31" => { "value" => "Right to Shared Ownership (RtSO)" },
+ "32" => { "value" => "London Living Rent — Shared Ownership" },
+ })
+ end
end
end
diff --git a/spec/models/form/sales/subsections/household_characteristics_spec.rb b/spec/models/form/sales/subsections/household_characteristics_spec.rb
index 33e9a1409..4645b7231 100644
--- a/spec/models/form/sales/subsections/household_characteristics_spec.rb
+++ b/spec/models/form/sales/subsections/household_characteristics_spec.rb
@@ -50,6 +50,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
working_situation_buyer_2_income_value_check
buyer_2_live_in_property
number_of_others_in_property
+ number_of_others_in_property_joint_purchase
person_2_known
person_2_relationship_to_buyer_1
person_2_age
@@ -82,6 +83,14 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
gender_5_retirement_value_check
person_5_working_situation
working_situation_5_retirement_value_check
+ person_6_known
+ person_6_relationship_to_buyer_1
+ person_6_age
+ age_6_retirement_value_check
+ person_6_gender_identity
+ gender_6_retirement_value_check
+ person_6_working_situation
+ working_situation_6_retirement_value_check
],
)
end
@@ -131,6 +140,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
working_situation_buyer_2_income_value_check
buyer_2_live_in_property
number_of_others_in_property
+ number_of_others_in_property_joint_purchase
person_2_known
person_2_relationship_to_buyer_1
person_2_age
@@ -163,6 +173,14 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model
gender_5_retirement_value_check
person_5_working_situation
working_situation_5_retirement_value_check
+ person_6_known
+ person_6_relationship_to_buyer_1
+ person_6_age
+ age_6_retirement_value_check
+ person_6_gender_identity
+ gender_6_retirement_value_check
+ person_6_working_situation
+ working_situation_6_retirement_value_check
],
)
end
diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb
index 7b9f7c7ef..b82fe6fe3 100644
--- a/spec/models/sales_log_spec.rb
+++ b/spec/models/sales_log_spec.rb
@@ -90,6 +90,30 @@ RSpec.describe SalesLog, type: :model do
expect(completed_sales_log.not_started?).to be(false)
expect(completed_sales_log.completed?).to be(true)
end
+
+ context "when proplen is not given" do
+ before do
+ Timecop.freeze(Time.zone.local(2023, 5, 1))
+ end
+
+ after do
+ Timecop.unfreeze
+ end
+
+ it "is set to completed for a log with a saledate before 23/24" do
+ completed_sales_log.update!(proplen: nil, saledate: Time.zone.local(2022, 5, 1))
+ expect(completed_sales_log.in_progress?).to be(false)
+ expect(completed_sales_log.not_started?).to be(false)
+ expect(completed_sales_log.completed?).to be(true)
+ end
+
+ it "is set to in_progress for a log with a saledate after 23/24" do
+ completed_sales_log.update!(proplen: nil, saledate: Time.zone.local(2023, 5, 1))
+ expect(completed_sales_log.in_progress?).to be(true)
+ expect(completed_sales_log.not_started?).to be(false)
+ expect(completed_sales_log.completed?).to be(false)
+ end
+ end
end
context "when filtering by organisation" do
@@ -283,6 +307,12 @@ RSpec.describe SalesLog, type: :model do
expect(record_from_db["hhmemb"]).to eq(6)
end
+ it "correctly derives and saves hhmemb if it's a joint purchase" do
+ sales_log.update!(jointpur: 2, jointmore: 2)
+ record_from_db = ActiveRecord::Base.connection.execute("select hhmemb from sales_logs where id=#{sales_log.id}").to_a[0]
+ expect(record_from_db["hhmemb"]).to eq(5)
+ end
+
it "correctly derives and saves totchild" do
record_from_db = ActiveRecord::Base.connection.execute("select totchild from sales_logs where id=#{sales_log.id}").to_a[0]
expect(record_from_db["totchild"]).to eq(2)
diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb
index ae7875e08..bdd76cded 100644
--- a/spec/models/validations/financial_validations_spec.rb
+++ b/spec/models/validations/financial_validations_spec.rb
@@ -990,7 +990,7 @@ RSpec.describe Validations::FinancialValidations do
end
context "and charges are not provided" do
- it "throws and error" do
+ xit "throws and error" do
record.period = 3
record.chcharge = nil
financial_validator.validate_care_home_charges(record)
diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb
index 7850008a1..846c266a5 100644
--- a/spec/services/imports/lettings_logs_import_service_spec.rb
+++ b/spec/services/imports/lettings_logs_import_service_spec.rb
@@ -47,11 +47,12 @@ RSpec.describe Imports::LettingsLogsImportService do
let(:lettings_log_id2) { "166fc004-392e-47a8-acb8-1c018734882b" }
let(:lettings_log_id3) { "00d2343e-d5fa-4c89-8400-ec3854b0f2b4" }
let(:lettings_log_id4) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
+ let(:sales_log) { "shared_ownership_sales_log" }
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
- .and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{lettings_log_id4}.xml])
+ .and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{lettings_log_id4}.xml #{remote_folder}/#{sales_log}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id}.xml")
.and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id))
@@ -64,6 +65,9 @@ RSpec.describe Imports::LettingsLogsImportService do
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id4}.xml")
.and_return(open_file(fixture_directory, lettings_log_id4), open_file(fixture_directory, lettings_log_id4))
+ allow(storage_service).to receive(:get_file_io)
+ .with("#{remote_folder}/#{sales_log}.xml")
+ .and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log))
end
it "successfully create all lettings logs" do
@@ -205,6 +209,110 @@ RSpec.describe Imports::LettingsLogsImportService do
end
end
+ context "and it has zero earnings" do
+ before do
+ lettings_log_xml.at_xpath("//meta:status").content = "submitted"
+ lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 0
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Where the income is 0, set earnings and income to blank and set incref to refused/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.earnings).to be_nil
+ expect(lettings_log.incref).to eq(1)
+ expect(lettings_log.net_income_known).to eq(2)
+ end
+ end
+
+ context "and an invalid tenancy length for tenancy type" do
+ before do
+ lettings_log_xml.at_xpath("//meta:status").content = "submitted"
+ lettings_log_xml.at_xpath("//xmlns:_2cYears").content = "1"
+ lettings_log_xml.at_xpath("//xmlns:Q2b").content = "4"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing tenancylength as invalid/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.tenancylength).to be_nil
+ expect(lettings_log.tenancy).to be_nil
+ end
+ end
+
+ context "and an lead tenant must be under 20 if childrens home or foster care" do
+ before do
+ lettings_log_xml.at_xpath("//meta:status").content = "submitted"
+ lettings_log_xml.at_xpath("//xmlns:Q11").content = "13"
+ lettings_log_xml.at_xpath("//xmlns:P1Age").content = "22"
+ end
+
+ it "intercepts the relevant validation error" do
+ expect(logger).to receive(:warn).with(/Removing age1 and prevten as incompatible/)
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.age1).to be_nil
+ expect(lettings_log.prevten).to be_nil
+ end
+ end
+
+ context "and is a carehome but missing carehome charge" do
+ let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
+
+ before do
+ lettings_log_xml.at_xpath("//meta:status").content = "submitted"
+ lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id
+ scheme2.update!(registered_under_care_act: 2)
+ lettings_log_xml.at_xpath("//xmlns:Q18b").content = ""
+ end
+
+ it "intercepts the relevant validation error" do
+ allow(logger).to receive(:warn)
+
+ expect { lettings_log_service.send(:create_log, lettings_log_xml) }
+ .not_to raise_error
+ end
+
+ it "clears out the invalid answers" do
+ allow(logger).to receive(:warn)
+
+ lettings_log_service.send(:create_log, lettings_log_xml)
+ lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
+
+ expect(lettings_log).not_to be_nil
+ expect(lettings_log.is_carehome).to be_truthy
+ expect(lettings_log.chcharge).to be_nil
+ end
+ end
+
context "and this is an internal transfer from a non social housing" do
before do
lettings_log_xml.at_xpath("//xmlns:Q11").content = "9 Residential care home"
diff --git a/spec/services/imports/sales_logs_import_service_spec.rb b/spec/services/imports/sales_logs_import_service_spec.rb
index f57e2f3be..7fd5de7de 100644
--- a/spec/services/imports/sales_logs_import_service_spec.rb
+++ b/spec/services/imports/sales_logs_import_service_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Imports::SalesLogsImportService do
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
- .and_return(%W[#{remote_folder}/shared_ownership_sales_log.xml #{remote_folder}/shared_ownership_sales_log2.xml #{remote_folder}/outright_sale_sales_log.xml #{remote_folder}/discounted_ownership_sales_log.xml])
+ .and_return(%W[#{remote_folder}/shared_ownership_sales_log.xml #{remote_folder}/shared_ownership_sales_log2.xml #{remote_folder}/outright_sale_sales_log.xml #{remote_folder}/discounted_ownership_sales_log.xml #{remote_folder}/lettings_log.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/shared_ownership_sales_log.xml")
.and_return(open_file(fixture_directory, "shared_ownership_sales_log"), open_file(fixture_directory, "shared_ownership_sales_log"))
@@ -51,6 +51,9 @@ RSpec.describe Imports::SalesLogsImportService do
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/discounted_ownership_sales_log.xml")
.and_return(open_file(fixture_directory, "discounted_ownership_sales_log"), open_file(fixture_directory, "discounted_ownership_sales_log"))
+ allow(storage_service).to receive(:get_file_io)
+ .with("#{remote_folder}/lettings_log.xml")
+ .and_return(open_file(fixture_directory, "lettings_log"), open_file(fixture_directory, "lettings_log"))
end
it "successfully creates all sales logs" do
@@ -540,40 +543,216 @@ RSpec.describe Imports::SalesLogsImportService do
allow(logger).to receive(:warn).and_return(nil)
end
- it "sets hholdcount to hhmemb - 1 if not answered and not joint purchase" do
- sales_log_xml.at_xpath("//xmlns:HHMEMB").content = "3"
+ it "sets hholdcount to last person the information is given for if HHMEMB is not set" do
sales_log_xml.at_xpath("//xmlns:joint").content = "2 No"
- sales_log_xml.at_xpath("//xmlns:LiveInOther").content = ""
+ sales_log_xml.at_xpath("//xmlns:HHMEMB").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Age").content = "20"
+ sales_log_xml.at_xpath("//xmlns:P3Sex").content = "R"
+ sales_log_xml.at_xpath("//xmlns:P4Age").content = "23"
sales_log_service.send(:create_log, sales_log_xml)
sales_log = SalesLog.find_by(old_id: sales_log_id)
- expect(sales_log&.hholdcount).to eq(2)
+ expect(sales_log&.hholdcount).to eq(3)
end
- it "sets hholdcount to hhmemb - 2 if not answered and joint purchase" do
+ it "sets hholdcount to last person the information is given for - buyers if HHMEMB is 0" do
sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
- sales_log_xml.at_xpath("//xmlns:HHMEMB").content = "3"
- sales_log_xml.at_xpath("//xmlns:LiveInOther").content = ""
+ sales_log_xml.at_xpath("//xmlns:HHMEMB").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Age").content = "20"
+ sales_log_xml.at_xpath("//xmlns:P3Sex").content = "R"
+ sales_log_xml.at_xpath("//xmlns:P4Age").content = "23"
sales_log_service.send(:create_log, sales_log_xml)
sales_log = SalesLog.find_by(old_id: sales_log_id)
- expect(sales_log&.hholdcount).to eq(1)
+ expect(sales_log&.hholdcount).to eq(2)
end
- it "sets hholdcount to 0 if HHMEMB is 0" do
+ it "sets hholdcount to 0 no information for people is given and HHMEMB is not set" do
sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:HHMEMB").content = ""
+ sales_log_xml.at_xpath("//xmlns:LiveInOther").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Sex").content = ""
+ sales_log_xml.at_xpath("//xmlns:P3Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P3Sex").content = ""
+ sales_log_xml.at_xpath("//xmlns:P4Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P4Sex").content = ""
+
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.hholdcount).to eq(0)
+ end
+
+ it "sets hholdcount to the 0 if no information for people is given and HHMEMB is 0" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "2 No"
sales_log_xml.at_xpath("//xmlns:HHMEMB").content = "0"
sales_log_xml.at_xpath("//xmlns:LiveInOther").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P2Sex").content = ""
+ sales_log_xml.at_xpath("//xmlns:P3Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P3Sex").content = ""
+ sales_log_xml.at_xpath("//xmlns:P4Age").content = ""
+ sales_log_xml.at_xpath("//xmlns:P4Sex").content = ""
sales_log_service.send(:create_log, sales_log_xml)
sales_log = SalesLog.find_by(old_id: sales_log_id)
expect(sales_log&.hholdcount).to eq(0)
end
+
+ it "doesn't hang if jointpur is not given" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = ""
+ sales_log_xml.at_xpath("//xmlns:HHMEMB").content = "0"
+
+ sales_log_service.send(:create_log, sales_log_xml)
+ end
+ end
+
+ context "when inferring income used" do
+ let(:sales_log_id) { "discounted_ownership_sales_log" }
+
+ before do
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "sets inc1mort and inc2mort to don't know if not answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:Q2Person1Mortgage").content = ""
+ sales_log_xml.at_xpath("//xmlns:Q2Person2MortApplication").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.inc1mort).to eq(3)
+ expect(sales_log&.inc2mort).to eq(3)
+ end
+
+ it "sets inc1mort and inc2mort correctly if answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:Q2Person1Mortgage").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:Q2Person2MortApplication").content = "2 No"
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.inc1mort).to eq(1)
+ expect(sales_log&.inc2mort).to eq(2)
+ end
+ end
+
+ context "when inferring buyer organisation" do
+ let(:sales_log_id) { "discounted_ownership_sales_log" }
+
+ before do
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "sets pregblank to true if no other organisations are selected" do
+ sales_log_xml.at_xpath("//xmlns:PREGYRHA").content = ""
+ sales_log_xml.at_xpath("//xmlns:PREGLA").content = ""
+ sales_log_xml.at_xpath("//xmlns:PREGHBA").content = ""
+ sales_log_xml.at_xpath("//xmlns:PREGOTHER").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.pregyrha).to eq(nil)
+ expect(sales_log&.pregla).to eq(nil)
+ expect(sales_log&.pregghb).to eq(nil)
+ expect(sales_log&.pregother).to eq(nil)
+ expect(sales_log&.pregblank).to eq(1)
+ end
+
+ it "sets pregblank and other organisation fields correctly if answered" do
+ sales_log_xml.at_xpath("//xmlns:PREGYRHA").content = "Yes"
+ sales_log_xml.at_xpath("//xmlns:PREGLA").content = "Yes"
+ sales_log_xml.at_xpath("//xmlns:PREGHBA").content = "Yes"
+ sales_log_xml.at_xpath("//xmlns:PREGOTHER").content = "Yes"
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.pregyrha).to eq(1)
+ expect(sales_log&.pregla).to eq(1)
+ expect(sales_log&.pregghb).to eq(1)
+ expect(sales_log&.pregother).to eq(1)
+ expect(sales_log&.pregblank).to eq(nil)
+ end
+ end
+
+ context "when setting default buyer 2 live in for discounted ownership" do
+ let(:sales_log_id) { "discounted_ownership_sales_log" }
+
+ before do
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "sets buy2livein to true if it is joint purchase and it's not answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:LiveInBuyer2").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.buy2livein).to eq(1)
+ end
+
+ it "sets buy2livein correctly if it's answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:LiveInBuyer2").content = "1 Yes"
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.buy2livein).to eq(1)
+ end
+ end
+
+ context "when setting default buyer 2 live in for shared ownership" do
+ let(:sales_log_id) { "shared_ownership_sales_log" }
+
+ before do
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "sets buy2livein to true if it is joint purchase and it's not answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:LiveInBuyer2").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.buy2livein).to eq(1)
+ end
+
+ it "sets buy2livein correctly if it's answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:LiveInBuyer2").content = "2 No"
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.buy2livein).to eq(2)
+ end
+ end
+
+ context "when setting default buyer 2 live in for outright sale" do
+ let(:sales_log_id) { "outright_sale_sales_log" }
+
+ before do
+ allow(logger).to receive(:warn).and_return(nil)
+ end
+
+ it "does not set buy2livein if it is joint purchase and it's not answered" do
+ sales_log_xml.at_xpath("//xmlns:joint").content = "1 Yes"
+ sales_log_xml.at_xpath("//xmlns:JointMore").content = "2 No"
+ sales_log_xml.at_xpath("//xmlns:LiveInBuyer2").content = ""
+ sales_log_service.send(:create_log, sales_log_xml)
+
+ sales_log = SalesLog.find_by(old_id: sales_log_id)
+ expect(sales_log&.buy2livein).to eq(nil)
+ end
end
end
end