diff --git a/Gemfile b/Gemfile index 741f484bd..f23a4db6f 100644 --- a/Gemfile +++ b/Gemfile @@ -70,6 +70,7 @@ group :development, :test do gem "byebug", platforms: %i[mri mingw x64_mingw] gem "dotenv-rails" gem "factory_bot_rails" + gem "faker" gem "pry-byebug" gem "parallel_tests" @@ -93,7 +94,6 @@ group :test do gem "capybara", require: false gem "capybara-lockstep" gem "capybara-screenshot" - gem "faker" gem "rspec-rails", require: false gem "selenium-webdriver", require: false gem "simplecov", require: false diff --git a/app/components/bulk_upload_error_row_component.rb b/app/components/bulk_upload_error_row_component.rb index f4f129cbc..887eef10c 100644 --- a/app/components/bulk_upload_error_row_component.rb +++ b/app/components/bulk_upload_error_row_component.rb @@ -2,7 +2,7 @@ class BulkUploadErrorRowComponent < ViewComponent::Base attr_reader :bulk_upload_errors def initialize(bulk_upload_errors:) - @bulk_upload_errors = sorted_errors(bulk_upload_errors) + @bulk_upload_errors = bulk_upload_errors super end @@ -62,10 +62,4 @@ class BulkUploadErrorRowComponent < ViewComponent::Base def sales? bulk_upload.log_type == "sales" end - -private - - def sorted_errors(errors) - errors.sort_by { |e| e.cell.rjust(3, "0") } - end end diff --git a/app/components/bulk_upload_error_summary_table_component.rb b/app/components/bulk_upload_error_summary_table_component.rb index 7b483077f..d15d5280e 100644 --- a/app/components/bulk_upload_error_summary_table_component.rb +++ b/app/components/bulk_upload_error_summary_table_component.rb @@ -16,8 +16,8 @@ class BulkUploadErrorSummaryTableComponent < ViewComponent::Base .bulk_upload_errors .group(:col, :field, :error) .having("count(*) >= ?", display_threshold) + .order_by_col .count - .sort_by { |el| el[0][0].rjust(3, "0") } end def errors? @@ -39,8 +39,8 @@ private .bulk_upload_errors .where(category: "setup") .group(:col, :field, :error) + .order_by_col .count - .sort_by { |el| el[0][0].rjust(3, "0") } end def display_threshold diff --git a/app/controllers/form_controller.rb b/app/controllers/form_controller.rb index dfa23425b..dbc5ba490 100644 --- a/app/controllers/form_controller.rb +++ b/app/controllers/form_controller.rb @@ -122,11 +122,9 @@ private def successful_redirect_path if is_referrer_check_answers? - page_ids = form.subsection_for_page(@page).pages.map(&:id) - page_index = page_ids.index(@page.id) - next_page_id = form.next_page(@page, @log, current_user) + next_page_id = form.next_page_id(@page, @log, current_user) next_page = form.get_page(next_page_id) - previous_page = form.previous_page(page_ids, page_index, @log, current_user) + previous_page = form.previous_page_id(@page, @log, current_user) if next_page&.interruption_screen? || next_page_id == previous_page || CONFIRMATION_PAGE_IDS.include?(next_page_id) return send("#{@log.class.name.underscore}_#{next_page_id}_path", @log, { referrer: "check_answers" }) diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 876f0e405..ffb2a9c9a 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -134,7 +134,7 @@ class LocationsController < ApplicationController def check_answers; end def confirm - flash[:notice] = "#{@location.postcode} #{@location.startdate.blank? || @location.startdate < Time.zone.now ? 'has been' : 'will be'} added to this scheme" + flash[:notice] = helpers.location_creation_success_notice(@location) redirect_to scheme_locations_path(@scheme) end diff --git a/app/helpers/collection_time_helper.rb b/app/helpers/collection_time_helper.rb index ed0fdf839..34426bab2 100644 --- a/app/helpers/collection_time_helper.rb +++ b/app/helpers/collection_time_helper.rb @@ -1,15 +1,15 @@ module CollectionTimeHelper - def collection_start_year(date) + def collection_start_year_for_date(date) window_end_date = Time.zone.local(date.year, 4, 1) date < window_end_date ? date.year - 1 : date.year end def current_collection_start_year - collection_start_year(Time.zone.now) + collection_start_year_for_date(Time.zone.now) end def collection_start_date(date) - Time.zone.local(collection_start_year(date), 4, 1) + Time.zone.local(collection_start_year_for_date(date), 4, 1) end def date_mid_collection_year_formatted(date) @@ -22,7 +22,7 @@ module CollectionTimeHelper end def collection_end_date(date) - Time.zone.local(collection_start_year(date) + 1, 3, 31).end_of_day + Time.zone.local(collection_start_year_for_date(date) + 1, 3, 31).end_of_day end def current_collection_end_date diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index 5c51fc88c..5bf7bc8ff 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -78,6 +78,12 @@ module LocationsHelper return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? end + def location_creation_success_notice(location) + if location.confirmed + "#{location.postcode} #{location.startdate.blank? || location.startdate.before?(Time.zone.now) ? 'has been' : 'will be'} added to this scheme" + end + end + private ActivePeriod = Struct.new(:from, :to) diff --git a/app/helpers/navigation_items_helper.rb b/app/helpers/navigation_items_helper.rb index 8db369d59..3def5547f 100644 --- a/app/helpers/navigation_items_helper.rb +++ b/app/helpers/navigation_items_helper.rb @@ -101,7 +101,7 @@ private end def subnav_details_path?(path) - path.include?("/organisations") && path.include?("/details") + path.include?("/organisations") && (path.include?("/details") || path.include?("/merge")) end def stock_owners_path?(path) diff --git a/app/helpers/question_view_helper.rb b/app/helpers/question_view_helper.rb index 3ff84bc19..fdb144c4e 100644 --- a/app/helpers/question_view_helper.rb +++ b/app/helpers/question_view_helper.rb @@ -13,6 +13,26 @@ module QuestionViewHelper } end + def answer_option_synonyms(resource) + return unless resource.instance_of?(Scheme) + + resource.locations.map(&:postcode).join(",") + end + + def answer_option_append(resource) + return unless resource.instance_of?(Scheme) + + confirmed_locations_count = resource.locations.confirmed.size + unconfirmed_locations_count = resource.locations.unconfirmed.size + "#{confirmed_locations_count} completed #{'location'.pluralize(confirmed_locations_count)}, #{unconfirmed_locations_count} incomplete #{'location'.pluralize(unconfirmed_locations_count)}" + end + + def answer_option_hint(resource) + return unless resource.instance_of?(Scheme) + + [resource.primary_client_group, resource.secondary_client_group].compact.join(", ") + end + private def label_size(page_header, conditional, question) diff --git a/app/helpers/tasklist_helper.rb b/app/helpers/tasklist_helper.rb index 9487d13a5..6a12cff29 100644 --- a/app/helpers/tasklist_helper.rb +++ b/app/helpers/tasklist_helper.rb @@ -15,7 +15,7 @@ module TasklistHelper if subsection.pages.first.routed_to?(log, current_user) subsection.pages.first.id else - log.form.next_page(subsection.pages.first, log, current_user) + log.form.next_page_id(subsection.pages.first, log, current_user) end end diff --git a/app/models/bulk_upload_error.rb b/app/models/bulk_upload_error.rb index df584b63e..0c298ddf8 100644 --- a/app/models/bulk_upload_error.rb +++ b/app/models/bulk_upload_error.rb @@ -1,3 +1,6 @@ class BulkUploadError < ApplicationRecord belongs_to :bulk_upload + + scope :order_by_cell, -> { order(Arel.sql("LPAD(cell, 10, '0')")) } + scope :order_by_col, -> { order(Arel.sql("LPAD(col, 10, '0')")) } end diff --git a/app/models/form.rb b/app/models/form.rb index 8f9dc47f9..80fed4444 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -61,30 +61,54 @@ class Form subsections.find { |s| s.pages.find { |p| p.id == page.id } } end - def next_page(page, log, current_user) + def next_page_id(page, log, current_user) return page.next_unresolved_page_id || :check_answers if log.unresolved page_ids = subsection_for_page(page).pages.map(&:id) page_index = page_ids.index(page.id) page_id = if page.interruption_screen? && log[page.questions[0].id] == 1 && page.routed_to?(log, current_user) - previous_page(page_ids, page_index, log, current_user) + previous_page_id(page, log, current_user) else page_ids[page_index + 1] end - nxt_page = get_page(page_id) + next_page = get_page(page_id) - return :check_answers if nxt_page.nil? - return nxt_page.id if nxt_page.routed_to?(log, current_user) + return :check_answers if next_page.nil? + return next_page.id if next_page.routed_to?(log, current_user) - next_page(nxt_page, log, current_user) + next_page_id(next_page, log, current_user) end def next_page_redirect_path(page, log, current_user) - nxt_page = next_page(page, log, current_user) - if nxt_page == :check_answers + next_page_id = next_page_id(page, log, current_user) + if next_page_id == :check_answers "#{type}_log_#{subsection_for_page(page).id}_check_answers_path" else - "#{type}_log_#{nxt_page}_path" + "#{type}_log_#{next_page_id}_path" + end + end + + def previous_page_id(page, log, current_user) + page_ids = subsection_for_page(page).pages.map(&:id) + page_index = page_ids.index(page.id) + return :tasklist if page_index.zero? + + page_id = page_ids[page_index - 1] + previous_page = get_page(page_id) + + return previous_page.id if previous_page.routed_to?(log, current_user) + + previous_page_id(previous_page, log, current_user) + end + + def previous_page_redirect_path(page, log, current_user, referrer) + previous_page_id = previous_page_id(page, log, current_user) + if referrer == "check_answers" + "#{type}_log_#{subsection_for_page(page).id}_check_answers_path" + elsif previous_page_id == :tasklist + "#{type}_log_path" + else + "#{type}_log_#{previous_page_id}_path" end end @@ -206,13 +230,6 @@ class Form questions.select { |q| q.type == "numeric" } end - def previous_page(page_ids, page_index, log, current_user) - prev_page = get_page(page_ids[page_index - 1]) - return prev_page.id if prev_page.routed_to?(log, current_user) - - previous_page(page_ids, page_index - 1, log, current_user) - end - def send_chain(arr, log) Array(arr).inject(log) { |o, a| o.public_send(*a) } end diff --git a/app/models/form/lettings/pages/care_home_weekly.rb b/app/models/form/lettings/pages/care_home_weekly.rb index ee8f7962e..56165ce62 100644 --- a/app/models/form/lettings/pages/care_home_weekly.rb +++ b/app/models/form/lettings/pages/care_home_weekly.rb @@ -3,18 +3,8 @@ class Form::Lettings::Pages::CareHomeWeekly < ::Form::Page super @id = "care_home_weekly" @depends_on = [ - { "period" => 1, "needstype" => 2, "household_charge" => 0 }, - { "period" => 1, "needstype" => 2, "household_charge" => nil }, - { "period" => 5, "needstype" => 2, "household_charge" => 0 }, - { "period" => 5, "needstype" => 2, "household_charge" => nil }, - { "period" => 6, "needstype" => 2, "household_charge" => 0 }, - { "period" => 6, "needstype" => 2, "household_charge" => nil }, - { "period" => 7, "needstype" => 2, "household_charge" => 0 }, - { "period" => 7, "needstype" => 2, "household_charge" => nil }, - { "period" => 8, "needstype" => 2, "household_charge" => 0 }, - { "period" => 8, "needstype" => 2, "household_charge" => nil }, - { "period" => 9, "needstype" => 2, "household_charge" => 0 }, - { "period" => 9, "needstype" => 2, "household_charge" => nil }, + { "rent_and_charges_paid_weekly?" => true, "is_supported_housing?" => true, "household_charge" => 0 }, + { "rent_and_charges_paid_weekly?" => true, "is_supported_housing?" => true, "household_charge" => nil }, ] end diff --git a/app/models/form/lettings/pages/max_rent_value_check.rb b/app/models/form/lettings/pages/max_rent_value_check.rb index b71bc6baf..956e07f44 100644 --- a/app/models/form/lettings/pages/max_rent_value_check.rb +++ b/app/models/form/lettings/pages/max_rent_value_check.rb @@ -4,14 +4,20 @@ class Form::Lettings::Pages::MaxRentValueCheck < ::Form::Page @depends_on = [{ "rent_in_soft_max_range?" => true }] @title_text = { "translation" => "soft_validations.rent.outside_range_title", - "arguments" => [{ "key" => "brent", "label" => true, "i18n_template" => "brent" }], + "arguments" => [ + { + "key" => "brent", + "label" => true, + "i18n_template" => "brent", + }, + ], } @informative_text = { "translation" => "soft_validations.rent.max_hint_text", "arguments" => [ { - "key" => "soft_max_for_period", - "label" => false, + "key" => "field_formatted_as_currency", + "arguments_for_key" => "soft_max_for_period", "i18n_template" => "soft_max_for_period", }, ], diff --git a/app/models/form/lettings/pages/min_rent_value_check.rb b/app/models/form/lettings/pages/min_rent_value_check.rb index 3a7cf8d10..279de4552 100644 --- a/app/models/form/lettings/pages/min_rent_value_check.rb +++ b/app/models/form/lettings/pages/min_rent_value_check.rb @@ -4,14 +4,18 @@ class Form::Lettings::Pages::MinRentValueCheck < ::Form::Page @depends_on = [{ "rent_in_soft_min_range?" => true }] @title_text = { "translation" => "soft_validations.rent.outside_range_title", - "arguments" => [{ "key" => "brent", "label" => true, "i18n_template" => "brent" }], + "arguments" => [{ + "key" => "brent", + "label" => true, + "i18n_template" => "brent", + }], } @informative_text = { "translation" => "soft_validations.rent.min_hint_text", "arguments" => [ { - "key" => "soft_min_for_period", - "label" => false, + "key" => "field_formatted_as_currency", + "arguments_for_key" => "soft_min_for_period", "i18n_template" => "soft_min_for_period", }, ], diff --git a/app/models/form/lettings/pages/net_income_value_check.rb b/app/models/form/lettings/pages/net_income_value_check.rb index 9a9c1061f..0569b86e9 100644 --- a/app/models/form/lettings/pages/net_income_value_check.rb +++ b/app/models/form/lettings/pages/net_income_value_check.rb @@ -7,8 +7,16 @@ class Form::Lettings::Pages::NetIncomeValueCheck < ::Form::Page @informative_text = { "translation" => "soft_validations.net_income.hint_text", "arguments" => [ - { "key" => "ecstat1", "label" => true, "i18n_template" => "ecstat1" }, - { "key" => "earnings", "label" => true, "i18n_template" => "earnings" }, + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "ecstat1", + "i18n_template" => "ecstat1", + }, + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "earnings", + "i18n_template" => "earnings", + }, ], } end diff --git a/app/models/form/lettings/pages/outstanding_amount.rb b/app/models/form/lettings/pages/outstanding_amount.rb index d624433ea..22d06c2c8 100644 --- a/app/models/form/lettings/pages/outstanding_amount.rb +++ b/app/models/form/lettings/pages/outstanding_amount.rb @@ -2,7 +2,7 @@ class Form::Lettings::Pages::OutstandingAmount < ::Form::Page def initialize(id, hsh, subsection) super @id = "outstanding_amount" - @depends_on = [{ "hb" => 1, "hbrentshortfall" => 1 }, { "hb" => 6, "hbrentshortfall" => 1 }] + @depends_on = [{ "receives_housing_related_benefits?" => true, "has_housing_benefit_rent_shortfall?" => true }] end def questions diff --git a/app/models/form/lettings/pages/rent_4_weekly.rb b/app/models/form/lettings/pages/rent_4_weekly.rb index fd8518e8e..e71cd7ffa 100644 --- a/app/models/form/lettings/pages/rent_4_weekly.rb +++ b/app/models/form/lettings/pages/rent_4_weekly.rb @@ -4,10 +4,8 @@ class Form::Lettings::Pages::Rent4Weekly < ::Form::Page @id = "rent_4_weekly" @header = "Household rent and charges" @depends_on = [ - { "household_charge" => 0, "period" => 3, "is_carehome" => 0 }, - { "household_charge" => nil, "period" => 3, "is_carehome" => 0 }, - { "household_charge" => 0, "period" => 3, "is_carehome" => nil }, - { "household_charge" => nil, "period" => 3, "is_carehome" => nil }, + { "household_charge" => 0, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, + { "household_charge" => nil, "rent_and_charges_paid_every_4_weeks?" => true, "is_carehome?" => false }, ] end diff --git a/app/models/form/lettings/pages/rent_bi_weekly.rb b/app/models/form/lettings/pages/rent_bi_weekly.rb index 66ebef76b..0b1b9c884 100644 --- a/app/models/form/lettings/pages/rent_bi_weekly.rb +++ b/app/models/form/lettings/pages/rent_bi_weekly.rb @@ -4,10 +4,8 @@ class Form::Lettings::Pages::RentBiWeekly < ::Form::Page @id = "rent_bi_weekly" @header = "Household rent and charges" @depends_on = [ - { "household_charge" => 0, "period" => 2, "is_carehome" => 0 }, - { "household_charge" => nil, "period" => 2, "is_carehome" => 0 }, - { "household_charge" => 0, "period" => 2, "is_carehome" => nil }, - { "household_charge" => nil, "period" => 2, "is_carehome" => nil }, + { "household_charge" => nil, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, + { "household_charge" => 0, "rent_and_charges_paid_every_2_weeks?" => true, "is_carehome?" => false }, ] end diff --git a/app/models/form/lettings/pages/rent_monthly.rb b/app/models/form/lettings/pages/rent_monthly.rb index 04664bc93..d6af7a08c 100644 --- a/app/models/form/lettings/pages/rent_monthly.rb +++ b/app/models/form/lettings/pages/rent_monthly.rb @@ -4,10 +4,8 @@ class Form::Lettings::Pages::RentMonthly < ::Form::Page @id = "rent_monthly" @header = "Household rent and charges" @depends_on = [ - { "household_charge" => 0, "period" => 4, "is_carehome" => 0 }, - { "household_charge" => nil, "period" => 4, "is_carehome" => 0 }, - { "household_charge" => 0, "period" => 4, "is_carehome" => nil }, - { "household_charge" => nil, "period" => 4, "is_carehome" => nil }, + { "household_charge" => nil, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, + { "household_charge" => 0, "rent_and_charges_paid_monthly?" => true, "is_carehome?" => false }, ] end diff --git a/app/models/form/lettings/pages/rent_weekly.rb b/app/models/form/lettings/pages/rent_weekly.rb index ab89b31af..4f1709820 100644 --- a/app/models/form/lettings/pages/rent_weekly.rb +++ b/app/models/form/lettings/pages/rent_weekly.rb @@ -4,30 +4,8 @@ class Form::Lettings::Pages::RentWeekly < ::Form::Page @id = "rent_weekly" @header = "Household rent and charges" @depends_on = [ - { "period" => 1, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 1, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 5, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 5, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 6, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 6, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 7, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 7, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 8, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 8, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 9, "household_charge" => 0, "is_carehome" => 0 }, - { "period" => 9, "household_charge" => nil, "is_carehome" => 0 }, - { "period" => 1, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 1, "household_charge" => nil, "is_carehome" => nil }, - { "period" => 5, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 5, "household_charge" => nil, "is_carehome" => nil }, - { "period" => 6, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 6, "household_charge" => nil, "is_carehome" => nil }, - { "period" => 7, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 7, "household_charge" => nil, "is_carehome" => nil }, - { "period" => 8, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 8, "household_charge" => nil, "is_carehome" => nil }, - { "period" => 9, "household_charge" => 0, "is_carehome" => nil }, - { "period" => 9, "household_charge" => nil, "is_carehome" => nil }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => 0, "is_carehome?" => false }, + { "rent_and_charges_paid_weekly?" => true, "household_charge" => nil, "is_carehome?" => false }, ] end diff --git a/app/models/form/lettings/pages/uprn.rb b/app/models/form/lettings/pages/uprn.rb index 7b6b90f1a..f50111798 100644 --- a/app/models/form/lettings/pages/uprn.rb +++ b/app/models/form/lettings/pages/uprn.rb @@ -6,14 +6,13 @@ class Form::Lettings::Pages::Uprn < ::Form::Page def questions @questions ||= [ + Form::Lettings::Questions::UprnKnown.new(nil, nil, self), Form::Lettings::Questions::Uprn.new(nil, nil, self), ] end def routed_to?(log, _current_user = nil) - return false if log.is_supported_housing? - - log.uprn_known == 1 + !log.is_supported_housing? end def skip_text diff --git a/app/models/form/lettings/pages/uprn_known.rb b/app/models/form/lettings/pages/uprn_known.rb deleted file mode 100644 index 1ded1ba82..000000000 --- a/app/models/form/lettings/pages/uprn_known.rb +++ /dev/null @@ -1,16 +0,0 @@ -class Form::Lettings::Pages::UprnKnown < ::Form::Page - def initialize(id, hsh, subsection) - super - @id = "uprn_known" - end - - def questions - @questions ||= [ - Form::Lettings::Questions::UprnKnown.new(nil, nil, self), - ] - end - - def routed_to?(log, _current_user = nil) - !log.is_supported_housing? - end -end diff --git a/app/models/form/lettings/questions/location_id.rb b/app/models/form/lettings/questions/location_id.rb index ee97724b5..94196534f 100644 --- a/app/models/form/lettings/questions/location_id.rb +++ b/app/models/form/lettings/questions/location_id.rb @@ -27,7 +27,7 @@ class Form::Lettings::Questions::LocationId < ::Form::Question def displayed_answer_options(lettings_log, _user = nil) return {} unless lettings_log.scheme - scheme_location_ids = lettings_log.scheme.locations.pluck(:id) + scheme_location_ids = lettings_log.scheme.locations.confirmed.pluck(:id) answer_options.select { |k, _v| scheme_location_ids.include?(k.to_i) } end diff --git a/app/models/form/lettings/questions/period.rb b/app/models/form/lettings/questions/period.rb index 08a8510c4..c4f476c7f 100644 --- a/app/models/form/lettings/questions/period.rb +++ b/app/models/form/lettings/questions/period.rb @@ -15,11 +15,12 @@ class Form::Lettings::Questions::Period < ::Form::Question "2" => { "value" => "Every 2 weeks" }, "3" => { "value" => "Every 4 weeks" }, "4" => { "value" => "Every calendar month" }, - "5" => { "value" => "Weekly for 50 weeks" }, - "6" => { "value" => "Weekly for 49 weeks" }, - "7" => { "value" => "Weekly for 48 weeks" }, - "8" => { "value" => "Weekly for 47 weeks" }, "9" => { "value" => "Weekly for 46 weeks" }, + "8" => { "value" => "Weekly for 47 weeks" }, + "7" => { "value" => "Weekly for 48 weeks" }, + "6" => { "value" => "Weekly for 49 weeks" }, + "5" => { "value" => "Weekly for 50 weeks" }, "1" => { "value" => "Weekly for 52 weeks" }, + "10" => { "value" => "Weekly for 53 weeks" }, }.freeze end diff --git a/app/models/form/lettings/questions/scheme_id.rb b/app/models/form/lettings/questions/scheme_id.rb index a9147ba5f..487b1b2c4 100644 --- a/app/models/form/lettings/questions/scheme_id.rb +++ b/app/models/form/lettings/questions/scheme_id.rb @@ -9,6 +9,11 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question @guidance_position = GuidancePosition::BOTTOM @guidance_partial = "scheme_selection" @question_number = 9 + @inferred_answers = { + "location.name": { + "scheme_has_multiple_locations?": false, + }, + } end def answer_options @@ -41,6 +46,10 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question !supported_housing_selected?(lettings_log) end + def get_extra_check_answer_value(lettings_log) + lettings_log.form.get_question("postcode_full", nil).label_from_value(lettings_log.postcode_full) unless lettings_log.scheme_has_multiple_locations? + end + private def supported_housing_selected?(lettings_log) diff --git a/app/models/form/lettings/questions/tshortfall.rb b/app/models/form/lettings/questions/tshortfall.rb index af8d32c9c..69697ca44 100644 --- a/app/models/form/lettings/questions/tshortfall.rb +++ b/app/models/form/lettings/questions/tshortfall.rb @@ -20,6 +20,7 @@ class Form::Lettings::Questions::Tshortfall < ::Form::Question { "label" => " every week for 47 weeks", "depends_on" => { "period" => 8 } }, { "label" => " every week for 46 weeks", "depends_on" => { "period" => 9 } }, { "label" => " every week for 52 weeks", "depends_on" => { "period" => 1 } }, + { "label" => " every week for 53 weeks", "depends_on" => { "period" => 10 } }, ] @question_number = 100 end diff --git a/app/models/form/lettings/questions/uprn.rb b/app/models/form/lettings/questions/uprn.rb index efe9a4ea4..95ade90ad 100644 --- a/app/models/form/lettings/questions/uprn.rb +++ b/app/models/form/lettings/questions/uprn.rb @@ -5,9 +5,14 @@ class Form::Lettings::Questions::Uprn < ::Form::Question @check_answer_label = "UPRN" @header = "What is the property's UPRN" @type = "text" - @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355." @width = 10 @question_number = 11 + @inferred_check_answers_value = [ + { + "condition" => { "uprn_known" => 0 }, + "value" => "Not known", + }, + ] end def unanswered_error_message @@ -15,6 +20,8 @@ class Form::Lettings::Questions::Uprn < ::Form::Question end def get_extra_check_answer_value(log) + return unless log.uprn_known == 1 + value = [ log.address_line1, log.address_line2, @@ -28,8 +35,4 @@ class Form::Lettings::Questions::Uprn < ::Form::Question "\n\n#{value.join("\n")}" end - - def hidden_in_check_answers?(log, _current_user = nil) - log.uprn_known != 1 - end end diff --git a/app/models/form/lettings/questions/uprn_known.rb b/app/models/form/lettings/questions/uprn_known.rb index d206885fb..816a31ffb 100644 --- a/app/models/form/lettings/questions/uprn_known.rb +++ b/app/models/form/lettings/questions/uprn_known.rb @@ -8,6 +8,8 @@ class Form::Lettings::Questions::UprnKnown < ::Form::Question @answer_options = ANSWER_OPTIONS @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.

You can continue without the UPRN, but it means we will need you to enter the address of the property." + @conditional_for = { "uprn" => [1] } + @hidden_in_check_answers = true end ANSWER_OPTIONS = { diff --git a/app/models/form/lettings/subsections/property_information.rb b/app/models/form/lettings/subsections/property_information.rb index f2dba28e5..0f921d4a5 100644 --- a/app/models/form/lettings/subsections/property_information.rb +++ b/app/models/form/lettings/subsections/property_information.rb @@ -34,7 +34,6 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection def uprn_questions if form.start_date.year >= 2023 [ - Form::Lettings::Pages::UprnKnown.new(nil, nil, self), Form::Lettings::Pages::Uprn.new(nil, nil, self), Form::Lettings::Pages::UprnConfirmation.new(nil, nil, self), Form::Lettings::Pages::Address.new(nil, nil, self), diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 19b9de163..8e8c26739 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -226,24 +226,6 @@ class Form::Question label end - def answer_option_synonyms(resource) - return unless resource.respond_to?(:synonyms) - - resource.synonyms - end - - def answer_option_append(resource) - return unless resource.respond_to?(:appended_text) - - resource.appended_text - end - - def answer_option_hint(resource) - return unless resource.respond_to?(:hint) - - resource.hint - end - def answer_selected?(log, answer) return false unless type == "select" @@ -317,7 +299,11 @@ private end def enabled_inferred_answers(inferred_answers, log) - inferred_answers.filter { |_key, value| value.all? { |condition_key, condition_value| log[condition_key] == condition_value } } + inferred_answers.filter do |_attribute, condition| + condition.all? do |condition_key, condition_value| + log.public_send(condition_key) == condition_value + end + end end def inferred_answer_value(log) diff --git a/app/models/form/sales/pages/buyer_live_in_value_check.rb b/app/models/form/sales/pages/buyer_live_in_value_check.rb new file mode 100644 index 000000000..067ba96ca --- /dev/null +++ b/app/models/form/sales/pages/buyer_live_in_value_check.rb @@ -0,0 +1,21 @@ +class Form::Sales::Pages::BuyerLiveInValueCheck < Form::Sales::Pages::Person + def initialize(id, hsh, subsection, person_index:) + super + @depends_on = [ + { + "buyer#{person_index}_livein_wrong_for_ownership_type?" => true, + }, + ] + @title_text = { + "translation" => "soft_validations.buyer#{person_index}_livein_wrong_for_ownership_type.title_text", + "arguments" => [{ "key" => "ownership_scheme", "label" => false, "i18n_template" => "ownership_scheme" }], + } + @informative_text = {} + end + + def questions + @questions ||= [ + Form::Sales::Questions::BuyerLiveInValueCheck.new(nil, nil, self, person_index: @person_index), + ] + end +end diff --git a/app/models/form/sales/pages/discounted_sale_value_check.rb b/app/models/form/sales/pages/discounted_sale_value_check.rb index 8ff48a0bd..3c1b010f2 100644 --- a/app/models/form/sales/pages/discounted_sale_value_check.rb +++ b/app/models/form/sales/pages/discounted_sale_value_check.rb @@ -4,11 +4,23 @@ class Form::Sales::Pages::DiscountedSaleValueCheck < ::Form::Page @depends_on = depends_on @title_text = { "translation" => "soft_validations.discounted_sale_value.title_text", - "arguments" => [{ "key" => "value_with_discount", "label" => false, "i18n_template" => "value_with_discount" }], + "arguments" => [ + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "value_with_discount", + "i18n_template" => "value_with_discount", + }, + ], } @informative_text = { "translation" => "soft_validations.discounted_sale_value.informative_text", - "arguments" => [{ "key" => "mortgage_deposit_and_grant_total", "label" => false, "i18n_template" => "mortgage_deposit_and_grant_total" }], + "arguments" => [ + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "mortgage_deposit_and_grant_total", + "i18n_template" => "mortgage_deposit_and_grant_total", + }, + ], } @person_index = person_index @depends_on = [ diff --git a/app/models/form/sales/pages/percentage_discount_value_check.rb b/app/models/form/sales/pages/percentage_discount_value_check.rb new file mode 100644 index 000000000..1e3beb3e6 --- /dev/null +++ b/app/models/form/sales/pages/percentage_discount_value_check.rb @@ -0,0 +1,15 @@ +class Form::Sales::Pages::PercentageDiscountValueCheck < ::Form::Page + def initialize(id, hsh, subsection) + super + @title_text = { + "translation" => "soft_validations.percentage_discount_value.title_text", + "arguments" => [{ "key" => "discount", "label" => true, "i18n_template" => "discount" }], + } + @informative_text = {} + @depends_on = [{ "percentage_discount_invalid?" => true }] + end + + def questions + @questions ||= [Form::Sales::Questions::PercentageDiscountValueCheck.new(nil, nil, self)] + end +end diff --git a/app/models/form/sales/pages/shared_ownership_deposit_value_check.rb b/app/models/form/sales/pages/shared_ownership_deposit_value_check.rb index be2126482..4730248ed 100644 --- a/app/models/form/sales/pages/shared_ownership_deposit_value_check.rb +++ b/app/models/form/sales/pages/shared_ownership_deposit_value_check.rb @@ -11,8 +11,8 @@ class Form::Sales::Pages::SharedOwnershipDepositValueCheck < ::Form::Page "translation" => "soft_validations.shared_ownership_deposit.title_text", "arguments" => [ { - "key" => "expected_shared_ownership_deposit_value", - "label" => false, + "key" => "field_formatted_as_currency", + "arguments_for_key" => "expected_shared_ownership_deposit_value", "i18n_template" => "expected_shared_ownership_deposit_value", }, ], diff --git a/app/models/form/sales/pages/uprn.rb b/app/models/form/sales/pages/uprn.rb index e1835f8ca..ad247207f 100644 --- a/app/models/form/sales/pages/uprn.rb +++ b/app/models/form/sales/pages/uprn.rb @@ -6,6 +6,7 @@ class Form::Sales::Pages::Uprn < ::Form::Page def questions @questions ||= [ + Form::Sales::Questions::UprnKnown.new(nil, nil, self), Form::Sales::Questions::Uprn.new(nil, nil, self), ] end diff --git a/app/models/form/sales/pages/uprn_known.rb b/app/models/form/sales/pages/uprn_known.rb deleted file mode 100644 index e2cbfe63f..000000000 --- a/app/models/form/sales/pages/uprn_known.rb +++ /dev/null @@ -1,12 +0,0 @@ -class Form::Sales::Pages::UprnKnown < ::Form::Page - def initialize(id, hsh, subsection) - super - @id = "uprn_known" - end - - def questions - @questions ||= [ - Form::Sales::Questions::UprnKnown.new(nil, nil, self), - ] - end -end diff --git a/app/models/form/sales/questions/buyer_live_in_value_check.rb b/app/models/form/sales/questions/buyer_live_in_value_check.rb new file mode 100644 index 000000000..a4209c38c --- /dev/null +++ b/app/models/form/sales/questions/buyer_live_in_value_check.rb @@ -0,0 +1,24 @@ +class Form::Sales::Questions::BuyerLiveInValueCheck < ::Form::Question + def initialize(id, hsh, page, person_index:) + super(id, hsh, page) + @id = "buyer_livein_value_check" + @check_answer_label = "Buyer live in confirmation" + @type = "interruption_screen" + @answer_options = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + } + @hidden_in_check_answers = { + "depends_on" => [ + { + "buyer_livein_value_check" => 0, + }, + { + "buyer_livein_value_check" => 1, + }, + ], + } + @check_answers_card_number = person_index + @header = "Are you sure this is correct?" + end +end diff --git a/app/models/form/sales/questions/percentage_discount_value_check.rb b/app/models/form/sales/questions/percentage_discount_value_check.rb new file mode 100644 index 000000000..9ac5547b4 --- /dev/null +++ b/app/models/form/sales/questions/percentage_discount_value_check.rb @@ -0,0 +1,23 @@ +class Form::Sales::Questions::PercentageDiscountValueCheck < ::Form::Question + def initialize(id, hsh, page) + super + @id = "percentage_discount_value_check" + @check_answer_label = "Percentage discount confirmation" + @header = "Are you sure this is correct?" + @type = "interruption_screen" + @answer_options = { + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + } + @hidden_in_check_answers = { + "depends_on" => [ + { + "percentage_discount_value_check" => 0, + }, + { + "percentage_discount_value_check" => 1, + }, + ], + } + end +end diff --git a/app/models/form/sales/questions/uprn.rb b/app/models/form/sales/questions/uprn.rb index 7967a2035..6b51260a7 100644 --- a/app/models/form/sales/questions/uprn.rb +++ b/app/models/form/sales/questions/uprn.rb @@ -5,9 +5,14 @@ class Form::Sales::Questions::Uprn < ::Form::Question @check_answer_label = "UPRN" @header = "What is the property's UPRN" @type = "text" - @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355." @width = 10 @question_number = 14 + @inferred_check_answers_value = [ + { + "condition" => { "uprn_known" => 0 }, + "value" => "Not known", + }, + ] end def unanswered_error_message @@ -15,6 +20,8 @@ class Form::Sales::Questions::Uprn < ::Form::Question end def get_extra_check_answer_value(log) + return unless log.uprn_known == 1 + value = [ log.address_line1, log.address_line2, @@ -28,8 +35,4 @@ class Form::Sales::Questions::Uprn < ::Form::Question "\n\n#{value.join("\n")}" end - - def hidden_in_check_answers?(log, _current_user = nil) - log.uprn_known != 1 - end end diff --git a/app/models/form/sales/questions/uprn_known.rb b/app/models/form/sales/questions/uprn_known.rb index b07b0b7d7..22438e662 100644 --- a/app/models/form/sales/questions/uprn_known.rb +++ b/app/models/form/sales/questions/uprn_known.rb @@ -8,6 +8,14 @@ class Form::Sales::Questions::UprnKnown < ::Form::Question @answer_options = ANSWER_OPTIONS @hint_text = "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.

You can continue without the UPRN, but it means we will need you to enter the address of the property." + @conditional_for = { "uprn" => [1] } + @inferred_check_answers_value = [ + { + "condition" => { "uprn_known" => 0 }, + "value" => "Not known", + }, + ] + @hidden_in_check_answers = true end ANSWER_OPTIONS = { diff --git a/app/models/form/sales/subsections/discounted_ownership_scheme.rb b/app/models/form/sales/subsections/discounted_ownership_scheme.rb index 09813339d..52ee9e95c 100644 --- a/app/models/form/sales/subsections/discounted_ownership_scheme.rb +++ b/app/models/form/sales/subsections/discounted_ownership_scheme.rb @@ -11,6 +11,7 @@ class Form::Sales::Subsections::DiscountedOwnershipScheme < ::Form::Subsection Form::Sales::Pages::LivingBeforePurchase.new("living_before_purchase_discounted_ownership", nil, self, ownershipsch: 2), Form::Sales::Pages::AboutPriceRtb.new(nil, nil, self), Form::Sales::Pages::ExtraBorrowingValueCheck.new("extra_borrowing_price_value_check", nil, self), + Form::Sales::Pages::PercentageDiscountValueCheck.new("percentage_discount_value_check", nil, self), Form::Sales::Pages::AboutPriceNotRtb.new(nil, nil, self), Form::Sales::Pages::GrantValueCheck.new(nil, nil, self), Form::Sales::Pages::PurchasePriceOutrightOwnership.new("purchase_price_discounted_ownership", nil, self, ownershipsch: 2), diff --git a/app/models/form/sales/subsections/household_characteristics.rb b/app/models/form/sales/subsections/household_characteristics.rb index 922d95edd..64b0b95ea 100644 --- a/app/models/form/sales/subsections/household_characteristics.rb +++ b/app/models/form/sales/subsections/household_characteristics.rb @@ -26,6 +26,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Sales::Pages::RetirementValueCheck.new("working_situation_1_retirement_value_check", nil, self, person_index: 1), Form::Sales::Pages::Buyer1IncomeValueCheck.new("working_situation_buyer_1_income_value_check", nil, self), Form::Sales::Pages::Buyer1LiveInProperty.new(nil, nil, self), + Form::Sales::Pages::BuyerLiveInValueCheck.new("buyer_1_live_in_property_value_check", nil, self, person_index: 1), Form::Sales::Pages::Buyer2RelationshipToBuyer1.new(nil, nil, self), Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_relationship_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::Age2.new(nil, nil, self), @@ -40,6 +41,7 @@ class Form::Sales::Subsections::HouseholdCharacteristics < ::Form::Subsection Form::Sales::Pages::Buyer2IncomeValueCheck.new("working_situation_buyer_2_income_value_check", nil, self), Form::Sales::Pages::PersonStudentNotChildValueCheck.new("buyer_2_working_situation_student_not_child_value_check", nil, self, person_index: 2), Form::Sales::Pages::Buyer2LiveInProperty.new(nil, nil, self), + Form::Sales::Pages::BuyerLiveInValueCheck.new("buyer_2_live_in_property_value_check", nil, self, person_index: 2), 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), diff --git a/app/models/form/sales/subsections/property_information.rb b/app/models/form/sales/subsections/property_information.rb index cca34a764..74a064dca 100644 --- a/app/models/form/sales/subsections/property_information.rb +++ b/app/models/form/sales/subsections/property_information.rb @@ -13,6 +13,7 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection Form::Sales::Pages::AboutPriceValueCheck.new("about_price_bedrooms_value_check", nil, self), Form::Sales::Pages::PropertyUnitType.new(nil, nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_property_type_value_check", nil, self), + Form::Sales::Pages::PercentageDiscountValueCheck.new("percentage_discount_proptype_value_check", nil, self), Form::Sales::Pages::PropertyBuildingType.new(nil, nil, self), postcode_and_la_questions, Form::Sales::Pages::AboutPriceValueCheck.new("about_price_la_value_check", nil, self), @@ -23,7 +24,6 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection def uprn_questions if form.start_date.year >= 2023 [ - Form::Sales::Pages::UprnKnown.new(nil, nil, self), Form::Sales::Pages::Uprn.new(nil, nil, self), Form::Sales::Pages::UprnConfirmation.new(nil, nil, self), Form::Sales::Pages::Address.new(nil, nil, self), diff --git a/app/models/form/sales/subsections/setup.rb b/app/models/form/sales/subsections/setup.rb index d1bb9dd6b..c723b732c 100644 --- a/app/models/form/sales/subsections/setup.rb +++ b/app/models/form/sales/subsections/setup.rb @@ -19,6 +19,8 @@ class Form::Sales::Subsections::Setup < ::Form::Subsection Form::Sales::Pages::OldPersonsSharedOwnershipValueCheck.new("ownership_type_old_persons_shared_ownership_value_check", nil, self), Form::Sales::Pages::MonthlyChargesValueCheck.new("monthly_charges_type_value_check", nil, self), Form::Sales::Pages::DiscountedSaleValueCheck.new("discounted_sale_type_value_check", nil, self), + Form::Sales::Pages::BuyerLiveInValueCheck.new("buyer_1_live_in_property_type_value_check", nil, self, person_index: 1), + Form::Sales::Pages::BuyerLiveInValueCheck.new("buyer_2_live_in_property_type_value_check", nil, self, person_index: 2), Form::Sales::Pages::BuyerCompany.new(nil, nil, self), Form::Sales::Pages::BuyerLive.new(nil, nil, self), Form::Sales::Pages::JointPurchase.new(nil, nil, self), diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index 43db4ed81..6ea58e339 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -58,7 +58,7 @@ class LettingsLog < Log OPTIONAL_FIELDS = %w[rent_value_check first_time_property_let_as_social_housing tenancycode propcode chcharge].freeze RENT_TYPE_MAPPING_LABELS = { 1 => "Social Rent", 2 => "Affordable Rent", 3 => "Intermediate Rent" }.freeze HAS_BENEFITS_OPTIONS = [1, 6, 8, 7].freeze - NUM_OF_WEEKS_FROM_PERIOD = { 2 => 26, 3 => 13, 4 => 12, 5 => 50, 6 => 49, 7 => 48, 8 => 47, 9 => 46, 1 => 52 }.freeze + NUM_OF_WEEKS_FROM_PERIOD = { 2 => 26, 3 => 13, 4 => 12, 5 => 50, 6 => 49, 7 => 48, 8 => 47, 9 => 46, 1 => 52, 10 => 53 }.freeze SUFFIX_FROM_PERIOD = { 2 => "every 2 weeks", 3 => "every 4 weeks", 4 => "every month" }.freeze RETIREMENT_AGES = { "M" => 67, "F" => 60, "X" => 67 }.freeze @@ -203,7 +203,7 @@ class LettingsLog < Log needstype == 2 end - def has_hbrentshortfall? + def has_housing_benefit_rent_shortfall? # 1: Yes hbrentshortfall == 1 end @@ -506,7 +506,27 @@ class LettingsLog < Log end def care_home_charge_expected_not_provided? - is_carehome == 1 && chcharge.blank? + is_carehome? && chcharge.blank? + end + + def rent_and_charges_paid_weekly? + [1, 5, 6, 7, 8, 9, 10].include? period + end + + def rent_and_charges_paid_every_4_weeks? + period == 3 + end + + def rent_and_charges_paid_every_2_weeks? + period == 2 + end + + def rent_and_charges_paid_monthly? + period == 4 + end + + def is_carehome? + is_carehome == 1 end private diff --git a/app/models/location.rb b/app/models/location.rb index c2c2e5b4d..57393d9fb 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -24,6 +24,7 @@ class Location < ApplicationRecord scope :started, -> { where("startdate <= ?", Time.zone.today).or(where(startdate: nil)) } scope :active, -> { where(confirmed: true).and(started) } scope :confirmed, -> { where(confirmed: true) } + scope :unconfirmed, -> { where.not(confirmed: true) } LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h diff --git a/app/models/log.rb b/app/models/log.rb index 6a36b948d..33d3c4547 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -1,4 +1,6 @@ class Log < ApplicationRecord + include CollectionTimeHelper + self.abstract_class = true belongs_to :owning_organisation, class_name: "Organisation", optional: true @@ -50,6 +52,7 @@ class Log < ApplicationRecord presenter = UprnDataPresenter.new(service.result) + self.uprn_known = 1 self.uprn_confirmed = nil self.address_line1 = presenter.address_line1 self.address_line2 = presenter.address_line2 @@ -87,6 +90,8 @@ class Log < ApplicationRecord end def collection_period_open? + return false if older_than_previous_collection_year? + form.end_date > Time.zone.today end @@ -126,8 +131,20 @@ class Log < ApplicationRecord end end + def field_formatted_as_currency(field_name) + field_value = public_send(field_name) + format_as_currency(field_value) + end + private + # Handle logs that are older than previous collection start date + def older_than_previous_collection_year? + return false unless startdate + + startdate < previous_collection_start_date + end + def plural_gender_for_person(person_num) gender = public_send("sex#{person_num}".to_sym) return unless gender diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 38beb850f..ebb3ef4e3 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -43,7 +43,7 @@ class SalesLog < Log } scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org) } - OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check othtype discounted_sale_value_check].freeze + OPTIONAL_FIELDS = %w[saledate_check purchid monthly_charges_value_check old_persons_shared_ownership_value_check othtype discounted_sale_value_check buyer_livein_value_check].freeze RETIREMENT_AGES = { "M" => 65, "F" => 60, "X" => 65 }.freeze def lettings? @@ -216,7 +216,7 @@ class SalesLog < Log def expected_shared_ownership_deposit_value return unless value && equity - format_as_currency(value * equity / 100) + value * equity / 100 end def process_postcode(postcode, postcode_known_key, la_inferred_key, la_key) @@ -323,11 +323,6 @@ class SalesLog < Log format_as_currency(soft_min) end - def field_formatted_as_currency(field_name) - field_value = public_send(field_name) - format_as_currency(field_value) - end - def should_process_uprn_change? uprn_changed? && saledate && saledate.year >= 2023 end @@ -350,4 +345,15 @@ class SalesLog < Log def beds_for_la_sale_range beds.nil? ? nil : [beds, LaSaleRange::MAX_BEDS].min end + + def ownership_scheme + case ownershipsch + when 1 + "shared ownership" + when 2 + "discounted ownership" + when 3 + "outright sale" + end + end end diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 8418f9393..75b37dec6 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -161,18 +161,6 @@ class Scheme < ApplicationRecord ] end - def synonyms - locations.map(&:postcode).join(",") - end - - def appended_text - "#{locations.count { |location| location.startdate.blank? || location.startdate <= Time.zone.today }} locations" - end - - def hint - [primary_client_group, secondary_client_group].filter(&:present?).join(", ") - end - def care_acts_options_with_hints hints = { "Yes – part registered as a care home": "A proportion of units are registered as being a care home." } diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 7c684c4dd..857c4e193 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -4,7 +4,7 @@ module Validations::FinancialValidations # Validations methods need to be called 'validate_' to run on model save # or 'validate_' to run on submit as well def validate_outstanding_rent_amount(record) - if !record.has_hbrentshortfall? && record.tshortfall.present? + if !record.has_housing_benefit_rent_shortfall? && record.tshortfall.present? record.errors.add :tshortfall, :no_outstanding_charges, message: I18n.t("validations.financial.tshortfall.outstanding_amount_not_required") end end @@ -69,7 +69,7 @@ module Validations::FinancialValidations end def validate_tshortfall(record) - if record.has_hbrentshortfall? && no_known_benefits?(record) + if record.has_housing_benefit_rent_shortfall? && no_known_benefits?(record) record.errors.add :tshortfall, I18n.t("validations.financial.hbrentshortfall.outstanding_no_benefits") end end @@ -99,7 +99,7 @@ module Validations::FinancialValidations end if record.tcharge.present? && weekly_value_in_range(record, "tcharge", 0, 9.99) - record.errors.add :tcharge, I18n.t("validations.financial.tcharge.under_10") + record.errors.add :tcharge, :under_10, message: I18n.t("validations.financial.tcharge.under_10") end answered_questions = [record.tcharge, record.chcharge].concat(record.household_charge && record.household_charge == 1 ? [record.household_charge] : []) @@ -224,7 +224,7 @@ private end if record.weekly_value(record["brent"]) > rent_range.hard_max - record.errors.add :brent, I18n.t("validations.financial.brent.above_hard_max") + record.errors.add :brent, :over_hard_max, message: I18n.t("validations.financial.brent.above_hard_max") record.errors.add :beds, I18n.t("validations.financial.brent.beds.above_hard_max") record.errors.add :la, I18n.t("validations.financial.brent.la.above_hard_max") record.errors.add :postcode_known, I18n.t("validations.financial.brent.postcode_known.above_hard_max") diff --git a/app/models/validations/sales/sale_information_validations.rb b/app/models/validations/sales/sale_information_validations.rb index e4714e81a..42dbde2a5 100644 --- a/app/models/validations/sales/sale_information_validations.rb +++ b/app/models/validations/sales/sale_information_validations.rb @@ -48,7 +48,7 @@ module Validations::Sales::SaleInformationValidations end def validate_discounted_ownership_value(record) - return unless record.saledate && collection_start_year(record.saledate) >= 2024 + return unless record.saledate && collection_start_year_for_date(record.saledate) >= 2024 return unless record.value && record.deposit && record.ownershipsch return unless record.mortgage || record.mortgageused == 2 return unless record.discount || record.grant || record.type == 29 diff --git a/app/models/validations/sales/soft_validations.rb b/app/models/validations/sales/soft_validations.rb index d72118d05..19d150c7e 100644 --- a/app/models/validations/sales/soft_validations.rb +++ b/app/models/validations/sales/soft_validations.rb @@ -123,6 +123,30 @@ module Validations::Sales::SoftValidations mortgage_deposit_and_grant_total != value_with_discount && discounted_ownership_sale? end + def buyer1_livein_wrong_for_ownership_type? + return unless ownershipsch && buy1livein + + (discounted_ownership_sale? || shared_ownership_scheme?) && buy1livein == 2 + end + + def buyer2_livein_wrong_for_ownership_type? + return unless ownershipsch && buy2livein + return unless joint_purchase? + + (discounted_ownership_sale? || shared_ownership_scheme?) && buy2livein == 2 + end + + def percentage_discount_invalid? + return unless discount && proptype + + case proptype + when 1, 2 + discount > 50 + when 3, 4, 9 + discount > 35 + end + end + private def sale_range diff --git a/app/models/validations/setup_validations.rb b/app/models/validations/setup_validations.rb index 0865ebae6..bd12d3249 100644 --- a/app/models/validations/setup_validations.rb +++ b/app/models/validations/setup_validations.rb @@ -20,6 +20,14 @@ module Validations::SetupValidations location_during_startdate_validation(record, :location_id) end + def validate_scheme_has_confirmed_locations_validation(record) + return unless record.scheme + + unless record.scheme.locations.confirmed.any? + record.errors.add :scheme_id, I18n.t("validations.scheme.no_completed_locations") + end + end + def validate_scheme(record) location_during_startdate_validation(record, :scheme_id) scheme_during_startdate_validation(record, :scheme_id) diff --git a/app/models/validations/shared_validations.rb b/app/models/validations/shared_validations.rb index 57e1d05c6..f032a089c 100644 --- a/app/models/validations/shared_validations.rb +++ b/app/models/validations/shared_validations.rb @@ -7,6 +7,7 @@ module Validations::SharedValidations main_field_label = main_label || main_field.to_s.humanize(capitalize: false) other_field_label = other_label || other_field.to_s.humanize(capitalize: false) if record[main_field] == value_other && record[other_field].blank? + record.errors.add main_field.to_sym, I18n.t("validations.other_field_missing", main_field_label:, other_field_label:) record.errors.add other_field.to_sym, I18n.t("validations.other_field_missing", main_field_label:, other_field_label:) end diff --git a/app/services/bulk_upload/lettings/year2022/row_parser.rb b/app/services/bulk_upload/lettings/year2022/row_parser.rb index 255aabe97..bfb7940ed 100644 --- a/app/services/bulk_upload/lettings/year2022/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2022/row_parser.rb @@ -14,37 +14,37 @@ class BulkUpload::Lettings::Year2022::RowParser field_9: "What is the tenancy type?", field_10: "If 'Other', what is the tenancy type?", field_11: "What is the length of the fixed-term tenancy to the nearest year?", - field_12: "Age of Person 1", - field_13: "Age of Person 2", - field_14: "Age of Person 3", - field_15: "Age of Person 4", - field_16: "Age of Person 5", - field_17: "Age of Person 6", - field_18: "Age of Person 7", - field_19: "Age of Person 8", - field_20: "Gender identity of Person 1", - field_21: "Gender identity of Person 2", - field_22: "Gender identity of Person 3", - field_23: "Gender identity of Person 4", - field_24: "Gender identity of Person 5", - field_25: "Gender identity of Person 6", - field_26: "Gender identity of Person 7", - field_27: "Gender identity of Person 8", - field_28: "Relationship to Person 1 for Person 2", - field_29: "Relationship to Person 1 for Person 3", - field_30: "Relationship to Person 1 for Person 4", - field_31: "Relationship to Person 1 for Person 5", - field_32: "Relationship to Person 1 for Person 6", - field_33: "Relationship to Person 1 for Person 7", - field_34: "Relationship to Person 1 for Person 8", - field_35: "Working situation of Person 1", - field_36: "Working situation of Person 2", - field_37: "Working situation of Person 3", - field_38: "Working situation of Person 4", - field_39: "Working situation of Person 5", - field_40: "Working situation of Person 6", - field_41: "Working situation of Person 7", - field_42: "Working situation of Person 8", + field_12: "Age of person 1", + field_13: "Age of person 2", + field_14: "Age of person 3", + field_15: "Age of person 4", + field_16: "Age of person 5", + field_17: "Age of person 6", + field_18: "Age of person 7", + field_19: "Age of person 8", + field_20: "Gender identity of person 1", + field_21: "Gender identity of person 2", + field_22: "Gender identity of person 3", + field_23: "Gender identity of person 4", + field_24: "Gender identity of person 5", + field_25: "Gender identity of person 6", + field_26: "Gender identity of person 7", + field_27: "Gender identity of person 8", + field_28: "Relationship to person 1 for person 2", + field_29: "Relationship to person 1 for person 3", + field_30: "Relationship to person 1 for person 4", + field_31: "Relationship to person 1 for person 5", + field_32: "Relationship to person 1 for person 6", + field_33: "Relationship to person 1 for person 7", + field_34: "Relationship to person 1 for person 8", + field_35: "Working situation of person 1", + field_36: "Working situation of person 2", + field_37: "Working situation of person 3", + field_38: "Working situation of person 4", + field_39: "Working situation of person 5", + field_40: "Working situation of person 6", + field_41: "Working situation of person 7", + field_42: "Working situation of person 8", field_43: "What is the lead tenant's ethnic group?", field_44: "What is the lead tenant's nationality?", field_45: "Does anybody in the household have links to the UK armed forces?", @@ -340,10 +340,10 @@ class BulkUpload::Lettings::Year2022::RowParser return true if blank_row? - super - log.valid? + super + log.errors.each do |error| fields = field_mapping_for_errors[error.attribute] || [] @@ -650,7 +650,7 @@ private end def questions - log.form.subsections.flat_map { |ss| ss.applicable_questions(log) } + @questions ||= log.form.subsections.flat_map { |ss| ss.applicable_questions(log) } end def validate_nulls diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb index 60b5477ce..43b229aa3 100644 --- a/app/services/bulk_upload/lettings/year2023/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb @@ -292,6 +292,7 @@ class BulkUpload::Lettings::Year2023::RowParser validates :field_72, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 7 must be a number or the letter R" }, allow_blank: true validates :field_76, format: { with: /\A\d{1,3}\z|\AR\z/, message: "Age of person 8 must be a number or the letter R" }, allow_blank: true + validates :field_6, presence: { message: I18n.t("validations.not_answered", question: "property renewal") } validates :field_7, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (day)") } validates :field_8, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (month)") } validates :field_9, presence: { message: I18n.t("validations.not_answered", question: "tenancy start date (year)") } @@ -342,10 +343,10 @@ class BulkUpload::Lettings::Year2023::RowParser return true if blank_row? - super - log.valid? + super + log.errors.each do |error| fields = field_mapping_for_errors[error.attribute] || [] @@ -826,7 +827,7 @@ private end def questions - log.form.subsections.flat_map { |ss| ss.applicable_questions(log) } + @questions ||= log.form.subsections.flat_map { |ss| ss.applicable_questions(log) } end def attributes_for_log @@ -1050,8 +1051,6 @@ private 1 when 2 0 - when nil - rsnvac == 14 ? 1 : 0 else field_6 end diff --git a/app/services/bulk_upload/sales/year2022/row_parser.rb b/app/services/bulk_upload/sales/year2022/row_parser.rb index 965c3547a..6f38654e6 100644 --- a/app/services/bulk_upload/sales/year2022/row_parser.rb +++ b/app/services/bulk_upload/sales/year2022/row_parser.rb @@ -9,29 +9,29 @@ class BulkUpload::Sales::Year2022::RowParser field_4: "What is the year of the sale completion date? - YY", field_5: "This question has been removed", field_6: "Was the buyer interviewed for any of the answers you will provide on this log?", - field_7: "Age of Buyer 1", - field_8: "Age of Person 2", - field_9: "Age of Person 3", - field_10: "Age of Person 4", - field_11: "Age of Person 5", - field_12: "Age of Person 6", - field_13: "Gender identity of Buyer 1", - field_14: "Gender identity of Person 2", - field_15: "Gender identity of Person 3", - field_16: "Gender identity of Person 4", - field_17: "Gender identity of Person 5", - field_18: "Gender identity of Person 6", - field_19: "Relationship to Buyer 1 for Person 2", - field_20: "Relationship to Buyer 1 for Person 3", - field_21: "Relationship to Buyer 1 for Person 4", - field_22: "Relationship to Buyer 1 for Person 5", - field_23: "Relationship to Buyer 1 for Person 6", - field_24: "Working situation of Buyer 1", - field_25: "Working situation of Person 2", - field_26: "Working situation of Person 3", - field_27: "Working situation of Person 4", - field_28: "Working situation of Person 5", - field_29: "Working situation of Person 6", + field_7: "Age of buyer 1", + field_8: "Age of person 2", + field_9: "Age of person 3", + field_10: "Age of person 4", + field_11: "Age of person 5", + field_12: "Age of person 6", + field_13: "Gender identity of buyer 1", + field_14: "Gender identity of person 2", + field_15: "Gender identity of person 3", + field_16: "Gender identity of person 4", + field_17: "Gender identity of person 5", + field_18: "Gender identity of person 6", + field_19: "Relationship to buyer 1 for person 2", + field_20: "Relationship to buyer 1 for person 3", + field_21: "Relationship to buyer 1 for person 4", + field_22: "Relationship to buyer 1 for person 5", + field_23: "Relationship to buyer 1 for person 6", + field_24: "Working situation of buyer 1", + field_25: "Working situation of person 2", + field_26: "Working situation of person 3", + field_27: "Working situation of person 4", + field_28: "Working situation of person 5", + field_29: "Working situation of person 6", field_30: "What is buyer 1's ethnic group?", field_31: "What is buyer 1's nationality?", field_32: "What is buyer 1's gross annual income?", diff --git a/app/services/exports/lettings_log_export_service.rb b/app/services/exports/lettings_log_export_service.rb index 1592f545d..429361913 100644 --- a/app/services/exports/lettings_log_export_service.rb +++ b/app/services/exports/lettings_log_export_service.rb @@ -12,19 +12,20 @@ module Exports start_time = Time.zone.now logs_by_collection = retrieve_lettings_logs(start_time, full_update).group_by(&:collection_start_year) daily_run_number = get_daily_run_number - archives_for_manifest = [] + archives_for_manifest = {} base_number = LogsExport.where(empty_export: false).maximum(:base_number) || 1 available_collection_years.each do |collection| lettings_logs = logs_by_collection.fetch(collection, LettingsLog.none) export = build_export_run(collection, start_time, base_number, full_update) archives = write_export_archive(export, lettings_logs) - archives_for_manifest << archives if archives.any? + archives_for_manifest.merge!(archives) + export.empty_export = archives.empty? export.save! end - write_master_manifest(daily_run_number, archives_for_manifest.flatten) + write_master_manifest(daily_run_number, archives_for_manifest) end private @@ -129,7 +130,7 @@ module Exports headers = ["zip-name", "date-time zipped folder generated", "zip-file-uri"] csv_string = CSV.generate do |csv| csv << headers - archive_datetimes.each do |archive, datetime| + archive_datetimes.each do |(archive, datetime)| csv << [archive, datetime, "#{archive}.zip"] end end diff --git a/config/initializers/feature_toggle.rb b/app/services/feature_toggle.rb similarity index 86% rename from config/initializers/feature_toggle.rb rename to app/services/feature_toggle.rb index 125aa6770..eed6244d1 100644 --- a/config/initializers/feature_toggle.rb +++ b/app/services/feature_toggle.rb @@ -36,7 +36,11 @@ class FeatureToggle true end - def self.bulk_upload_logs? + def self.bulk_upload_lettings_logs? + !Rails.env.production? + end + + def self.bulk_upload_sales_logs? !Rails.env.production? end @@ -53,4 +57,8 @@ class FeatureToggle def self.collection_2023_2024_year_enabled? true end + + def self.merge_organisations_enabled? + !Rails.env.production? + end end diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb index 94fb2ec3e..01c71faef 100644 --- a/app/services/imports/lettings_logs_import_service.rb +++ b/app/services/imports/lettings_logs_import_service.rb @@ -302,6 +302,8 @@ module Imports %i[supcharg outside_the_range] => %w[brent scharge pscharge supcharg tcharge], %i[scharge outside_the_range] => %w[brent scharge pscharge supcharg tcharge], %i[location_id not_active] => %w[location_id scheme_id], + %i[tcharge under_10] => %w[brent scharge pscharge supcharg tcharge], + %i[brent over_hard_max] => %w[brent scharge pscharge supcharg tcharge], } (2..8).each do |person| diff --git a/app/services/imports/sales_logs_import_service.rb b/app/services/imports/sales_logs_import_service.rb index 2fb619619..2d6551189 100644 --- a/app/services/imports/sales_logs_import_service.rb +++ b/app/services/imports/sales_logs_import_service.rb @@ -155,6 +155,8 @@ module Imports attributes["monthly_charges_value_check"] = 0 attributes["student_not_child_value_check"] = 0 attributes["discounted_sale_value_check"] = 0 + attributes["buyer_livein_value_check"] = 0 + attributes["percentage_discount_value_check"] = 0 # Sets the log creator owner_id = meta_field_value(xml_doc, "owner-user-id").strip @@ -278,7 +280,9 @@ module Imports hodate_check saledate_check student_not_child_value_check - discounted_sale_value_check] + discounted_sale_value_check + buyer_livein_value_check + percentage_discount_value_check] end def check_status_completed(sales_log, previous_status) diff --git a/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb b/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb index f38178b7e..7524072a5 100644 --- a/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb +++ b/app/views/bulk_upload_lettings_logs/forms/checking_file.html.erb @@ -10,14 +10,14 @@ Upload lettings logs in bulk (<%= @form.year_combo %>)

We’re checking the file

-

Once this is done, we’ll email you the outcome.

+

Once this is done, we’ll email you the outcome.

- We’re checking for any missing data, issues or errors. Depending on the file size, this could take a few minutes. + We’re checking for any missing data, issues or errors. Depending on file size, this could take a few minutes.

- If there are errors we will email you a link to view all the errors. + If there are errors, we will email you to let you know how to fix them.

diff --git a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file.html.erb b/app/views/bulk_upload_lettings_logs/forms/prepare_your_file.html.erb index 56b8dff90..45c2be562 100644 --- a/app/views/bulk_upload_lettings_logs/forms/prepare_your_file.html.erb +++ b/app/views/bulk_upload_lettings_logs/forms/prepare_your_file.html.erb @@ -19,6 +19,7 @@

Create your file

diff --git a/app/views/bulk_upload_lettings_results/show.html.erb b/app/views/bulk_upload_lettings_results/show.html.erb index 67b01ff9d..dea114e63 100644 --- a/app/views/bulk_upload_lettings_results/show.html.erb +++ b/app/views/bulk_upload_lettings_results/show.html.erb @@ -13,7 +13,7 @@
- <% @bulk_upload.bulk_upload_errors.group_by(&:row).each do |_row, errors_for_row| %> + <% @bulk_upload.bulk_upload_errors.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %> <%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: errors_for_row) %> <% end %>
diff --git a/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb b/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb index b729abc09..c47a97d5e 100644 --- a/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb +++ b/app/views/bulk_upload_sales_logs/forms/checking_file.html.erb @@ -10,14 +10,14 @@ Upload sales logs in bulk (<%= @form.year_combo %>)

We’re checking the file

-

Once this is done, we’ll email you the outcome.

+

Once this is done, we’ll email you the outcome.

- We’re checking for any missing data, issues or errors. Depending on the file size, this could take a few minutes. + We’re checking for any missing data, issues or errors. Depending on file size, this could take a few minutes.

- If there are errors we will email you a link to view all the errors. + If there are errors, we will email you to let you know how to fix them.

diff --git a/app/views/bulk_upload_sales_logs/forms/prepare_your_file.html.erb b/app/views/bulk_upload_sales_logs/forms/prepare_your_file.html.erb index ad1449d3c..71e759306 100644 --- a/app/views/bulk_upload_sales_logs/forms/prepare_your_file.html.erb +++ b/app/views/bulk_upload_sales_logs/forms/prepare_your_file.html.erb @@ -19,6 +19,7 @@

Create your file

diff --git a/app/views/form/_select_question.html.erb b/app/views/form/_select_question.html.erb index c1ee8c3e0..5f410deef 100644 --- a/app/views/form/_select_question.html.erb +++ b/app/views/form/_select_question.html.erb @@ -7,14 +7,14 @@ "data-controller": "accessible-autocomplete", caption: caption(caption_text, page_header, conditional), hint: { text: question.hint_text&.html_safe }) do %> - <% answers.each do |answer| %> - - <% end %> + <% answers.each do |answer| %> + + <% end %> <% end %> <%= render partial: "form/guidance/#{question.guidance_partial}" if question.bottom_guidance? %> diff --git a/app/views/form/page.html.erb b/app/views/form/page.html.erb index 45711b0f1..9b4d14d9d 100644 --- a/app/views/form/page.html.erb +++ b/app/views/form/page.html.erb @@ -1,7 +1,7 @@ <% content_for :title, @page.header.presence || @page.questions.first.header.html_safe %> <% content_for :before_content do %> - <%= govuk_back_link(href: "javascript:history.back()") %> + <%= govuk_back_link(href: send(@log.form.previous_page_redirect_path(@page, @log, current_user, params[:referrer]), @log)) %> <% end %>
diff --git a/app/views/locations/availability.erb b/app/views/locations/availability.erb index 279c5110c..8a00ddc89 100644 --- a/app/views/locations/availability.erb +++ b/app/views/locations/availability.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: params[:referrer] == "check_answers" ? scheme_location_check_answers_path(@scheme, @location, route: params[:route]) : scheme_location_mobility_standards_path(@scheme, @location, route: params[:route]), ) %> <% end %> diff --git a/app/views/locations/check_answers.html.erb b/app/views/locations/check_answers.html.erb index 11272b5a9..b460ca464 100644 --- a/app/views/locations/check_answers.html.erb +++ b/app/views/locations/check_answers.html.erb @@ -3,7 +3,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: case params[:route] when "locations" scheme_locations_path(@scheme) diff --git a/app/views/locations/index.html.erb b/app/views/locations/index.html.erb index 469768b11..7294b9729 100644 --- a/app/views/locations/index.html.erb +++ b/app/views/locations/index.html.erb @@ -4,7 +4,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: "/schemes/#{@scheme.id}", ) %> <% end %> diff --git a/app/views/locations/local_authority.html.erb b/app/views/locations/local_authority.html.erb index 69b36b5be..347f85866 100644 --- a/app/views/locations/local_authority.html.erb +++ b/app/views/locations/local_authority.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: case params[:referrer] when "check_local_authority" scheme_location_check_answers_path(@scheme, @location, route: params[:route]) diff --git a/app/views/locations/mobility_standards.html.erb b/app/views/locations/mobility_standards.html.erb index 42bdb4bcf..da08f8bfa 100644 --- a/app/views/locations/mobility_standards.html.erb +++ b/app/views/locations/mobility_standards.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: params[:referrer] == "check_answers" ? scheme_location_check_answers_path(@scheme, @location, route: params[:route]) : scheme_location_type_of_unit_path(@scheme, @location, route: params[:route]), ) %> <% end %> diff --git a/app/views/locations/name.html.erb b/app/views/locations/name.html.erb index 322a1da22..e5853a71f 100644 --- a/app/views/locations/name.html.erb +++ b/app/views/locations/name.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: case params[:referrer] when "check_answers" scheme_location_check_answers_path(@scheme, @location, route: params[:route]) diff --git a/app/views/locations/postcode.html.erb b/app/views/locations/postcode.html.erb index 5ede463ad..fe0505926 100644 --- a/app/views/locations/postcode.html.erb +++ b/app/views/locations/postcode.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: if params[:referrer] == "check_answers" scheme_location_check_answers_path(@scheme, @location, route: params[:route]) else diff --git a/app/views/locations/show.html.erb b/app/views/locations/show.html.erb index 79876e5b8..299a19357 100644 --- a/app/views/locations/show.html.erb +++ b/app/views/locations/show.html.erb @@ -3,7 +3,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: scheme_locations_path(@scheme), ) %> <% end %> diff --git a/app/views/locations/toggle_active.html.erb b/app/views/locations/toggle_active.html.erb index 7b995b2b5..c7c8270b5 100644 --- a/app/views/locations/toggle_active.html.erb +++ b/app/views/locations/toggle_active.html.erb @@ -3,7 +3,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: scheme_location_path(@location.scheme, @location), ) %> <% end %> diff --git a/app/views/locations/type_of_unit.html.erb b/app/views/locations/type_of_unit.html.erb index 5ff4ed3f1..45b76ef67 100644 --- a/app/views/locations/type_of_unit.html.erb +++ b/app/views/locations/type_of_unit.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: params[:referrer] == "check_answers" ? scheme_location_check_answers_path(@scheme, @location, route: params[:route]) : scheme_location_units_path(@scheme, @location, route: params[:route]), ) %> <% end %> diff --git a/app/views/locations/units.html.erb b/app/views/locations/units.html.erb index 30a9b3eff..12365adbb 100644 --- a/app/views/locations/units.html.erb +++ b/app/views/locations/units.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: params[:referrer] == "check_answers" ? scheme_location_check_answers_path(@scheme, @location, route: params[:route]) : scheme_location_name_path(@scheme, @location, route: params[:route]), ) %> <% end %> diff --git a/app/views/logs/index.html.erb b/app/views/logs/index.html.erb index 2d88c9bd6..04209be73 100644 --- a/app/views/logs/index.html.erb +++ b/app/views/logs/index.html.erb @@ -55,8 +55,12 @@ <%= govuk_button_to "Create a new sales log", sales_logs_path, class: "govuk-!-margin-right-6" %> <% end %> - <% if FeatureToggle.bulk_upload_logs? %> - <%= govuk_button_link_to "Upload #{log_type_for_controller(controller)} logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %> + <% if FeatureToggle.bulk_upload_lettings_logs? && log_type_for_controller(controller) == "lettings" %> + <%= govuk_button_link_to "Upload lettings logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %> + <% end %> + + <% if FeatureToggle.bulk_upload_sales_logs? && log_type_for_controller(controller) == "sales" %> + <%= govuk_button_link_to "Upload sales logs in bulk", bulk_upload_path_for_controller(controller, id: "start"), secondary: true %> <% end %>
<% end %> diff --git a/app/views/organisations/merge.html.erb b/app/views/organisations/merge.html.erb new file mode 100644 index 000000000..7d72d08b7 --- /dev/null +++ b/app/views/organisations/merge.html.erb @@ -0,0 +1,48 @@ +<% content_for :before_content do %> + <% title = "Tell us if your organisation is merging" %> + <% content_for :title, title %> + + <%= govuk_back_link href: organisation_path %> +<% end %> +

Tell us if your organisation is merging

+ +
+
+

+ Use this service to tell us if your organisation is merging with one or more other organisations. You can also use it to tell us about past merges that have not yet been reported to CORE. +

+ +

Before you start

+

Regardless of the merge type, you’ll be asked for:

+
    +
  • the organisations merging in CORE
  • +
  • the merge type: for example one organisation absorbing the rest, or them all creating a new organisation
  • +
  • to confirm or update the telephone number
  • +
  • the merge date
  • +
  • if user email addresses will change with this merge
  • +
+ +

If email addresses are changing

+ <%= govuk_inset_text(text: "Update all user email addresses on CORE as soon as they change, so that everyone can still access their CORE account. ") %> +

+ Users must have access to their old email address, so they can confirm their new one. +

+ +

If merging into a new organisation

+

You'll also be asked for the new organisation’s:

+
    +
  • name
  • +
  • address
  • +
  • telephone number
  • +
  • housing provider type
  • +
  • Regulator of Social Housing registration number
  • +
  • held stock details
  • +
+ + <%= govuk_warning_text text: "You will not be able to submit your request without the above information. Do not start the form until you have obtained all of the information. " %> + <%= govuk_start_button( + text: "Start now", + href: "#", + ) %> +
+
diff --git a/app/views/organisations/show.html.erb b/app/views/organisations/show.html.erb index bbe9ae67a..4561e985b 100644 --- a/app/views/organisations/show.html.erb +++ b/app/views/organisations/show.html.erb @@ -35,6 +35,9 @@ <% end %> <% end %> + <% if FeatureToggle.merge_organisations_enabled? %> +

Is your organisation merging with another? <%= govuk_link_to "Let us know using this form", merge_organisation_path %>

+ <% end %>
diff --git a/app/views/schemes/confirm_secondary.html.erb b/app/views/schemes/confirm_secondary.html.erb index c145e573d..e267b3289 100644 --- a/app/views/schemes/confirm_secondary.html.erb +++ b/app/views/schemes/confirm_secondary.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/primary-client-group", ) %> <% end %> diff --git a/app/views/schemes/details.html.erb b/app/views/schemes/details.html.erb index 4d45213f3..0e4f3a7d9 100644 --- a/app/views/schemes/details.html.erb +++ b/app/views/schemes/details.html.erb @@ -1,10 +1,7 @@ <% content_for :title, "Create a new supported housing scheme" %> <% content_for :before_content do %> - <%= govuk_back_link( - text: "Back", - href: :back, - ) %> + <%= govuk_back_link(href: :back) %> <% end %> <%= form_for(@scheme, method: :patch) do |f| %> diff --git a/app/views/schemes/edit_name.html.erb b/app/views/schemes/edit_name.html.erb index 04e28c93a..1dc8bc147 100644 --- a/app/views/schemes/edit_name.html.erb +++ b/app/views/schemes/edit_name.html.erb @@ -1,10 +1,7 @@ <% content_for :title, "Scheme details" %> <% content_for :before_content do %> - <%= govuk_back_link( - text: "Back", - href: :back, - ) %> + <%= govuk_back_link(href: :back) %> <% end %> <%= form_for(@scheme, method: :patch) do |f| %> diff --git a/app/views/schemes/new.html.erb b/app/views/schemes/new.html.erb index ff4f4d3a9..81c5febbf 100644 --- a/app/views/schemes/new.html.erb +++ b/app/views/schemes/new.html.erb @@ -6,10 +6,7 @@ <% content_for :title, "Create a new supported housing scheme" %> <% content_for :before_content do %> - <%= govuk_back_link( - text: "Back", - href: "javascript:history.go(-1);", - ) %> + <%= govuk_back_link(href: "javascript:history.back()") %> <% end %>

diff --git a/app/views/schemes/primary_client_group.html.erb b/app/views/schemes/primary_client_group.html.erb index 610e916f4..8fe852c89 100644 --- a/app/views/schemes/primary_client_group.html.erb +++ b/app/views/schemes/primary_client_group.html.erb @@ -7,10 +7,7 @@ <% end %> <% content_for :before_content do %> - <%= govuk_back_link( - text: "Back", - href: back_button_path, - ) %> + <%= govuk_back_link(href: back_button_path) %> <% end %> <%= form_for(@scheme, method: :patch) do |f| %> diff --git a/app/views/schemes/secondary_client_group.html.erb b/app/views/schemes/secondary_client_group.html.erb index 4f48dab00..fe292b1c2 100644 --- a/app/views/schemes/secondary_client_group.html.erb +++ b/app/views/schemes/secondary_client_group.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/confirm-secondary-client-group", ) %> <% end %> diff --git a/app/views/schemes/show.html.erb b/app/views/schemes/show.html.erb index 5ef55f9f4..beb4508e0 100644 --- a/app/views/schemes/show.html.erb +++ b/app/views/schemes/show.html.erb @@ -3,7 +3,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: "/schemes", ) %> <% end %> diff --git a/app/views/schemes/support.html.erb b/app/views/schemes/support.html.erb index 0c06a059f..23948978b 100644 --- a/app/views/schemes/support.html.erb +++ b/app/views/schemes/support.html.erb @@ -2,7 +2,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: request.query_parameters["check_answers"] ? "/schemes/#{@scheme.id}/check-answers" : "/schemes/#{@scheme.id}/secondary-client-group", ) %> <% end %> diff --git a/app/views/schemes/toggle_active.html.erb b/app/views/schemes/toggle_active.html.erb index f2ecc4a1a..e989be995 100644 --- a/app/views/schemes/toggle_active.html.erb +++ b/app/views/schemes/toggle_active.html.erb @@ -3,7 +3,6 @@ <% content_for :before_content do %> <%= govuk_back_link( - text: "Back", href: scheme_details_path(@scheme), ) %> <% end %> diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index e13ce5516..9b5aa6bb8 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -7492,23 +7492,26 @@ "4": { "value": "Every calendar month" }, - "5": { - "value": "Weekly for 50 weeks" + "9": { + "value": "Weekly for 46 weeks" }, - "6": { - "value": "Weekly for 49 weeks" + "8": { + "value": "Weekly for 47 weeks" }, "7": { "value": "Weekly for 48 weeks" }, - "8": { - "value": "Weekly for 47 weeks" + "6": { + "value": "Weekly for 49 weeks" }, - "9": { - "value": "Weekly for 46 weeks" + "5": { + "value": "Weekly for 50 weeks" }, "1": { "value": "Weekly for 52 weeks" + }, + "10": { + "value": "Weekly for 53 weeks" } } } @@ -7558,63 +7561,13 @@ }, "depends_on": [ { - "period": 1, - "needstype": 2, + "rent_and_charges_paid_weekly?": true, + "is_supported_housing?": true, "household_charge": 0 }, { - "period": 1, - "needstype": 2, - "household_charge": null - }, - { - "period": 5, - "needstype": 2, - "household_charge": 0 - }, - { - "period": 5, - "needstype": 2, - "household_charge": null - }, - { - "period": 6, - "needstype": 2, - "household_charge": 0 - }, - { - "period": 6, - "needstype": 2, - "household_charge": null - }, - { - "period": 7, - "needstype": 2, - "household_charge": 0 - }, - { - "period": 7, - "needstype": 2, - "household_charge": null - }, - { - "period": 8, - "needstype": 2, - "household_charge": 0 - }, - { - "period": 8, - "needstype": 2, - "household_charge": null - }, - { - "period": 9, - "needstype": 2, - "household_charge": 0 - }, - { - "period": 9, - "needstype": 2, + "rent_and_charges_paid_weekly?": true, + "is_supported_housing?": true, "household_charge": null } ] @@ -7898,124 +7851,14 @@ }, "depends_on": [ { - "period": 1, - "household_charge": 0, - "is_carehome": 0 - }, - { - "period": 1, - "household_charge": null, - "is_carehome": 0 - }, - { - "period": 5, - "household_charge": 0, - "is_carehome": 0 - }, - { - "period": 5, - "household_charge": null, - "is_carehome": 0 - }, - { - "period": 6, - "household_charge": 0, - "is_carehome": 0 - }, - { - "period": 6, - "household_charge": null, - "is_carehome": 0 - }, - { - "period": 7, - "household_charge": 0, - "is_carehome": 0 - }, - { - "period": 7, - "household_charge": null, - "is_carehome": 0 - }, - { - "period": 8, + "rent_and_charges_paid_weekly?": true, "household_charge": 0, - "is_carehome": 0 + "is_carehome?": false }, { - "period": 8, + "rent_and_charges_paid_weekly?": true, "household_charge": null, - "is_carehome": 0 - }, - { - "period": 9, - "household_charge": 0, - "is_carehome": 0 - }, - { - "period": 9, - "household_charge": null, - "is_carehome": 0 - }, - { - "period": 1, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 1, - "household_charge": null, - "is_carehome": null - }, - { - "period": 5, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 5, - "household_charge": null, - "is_carehome": null - }, - { - "period": 6, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 6, - "household_charge": null, - "is_carehome": null - }, - { - "period": 7, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 7, - "household_charge": null, - "is_carehome": null - }, - { - "period": 8, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 8, - "household_charge": null, - "is_carehome": null - }, - { - "period": 9, - "household_charge": 0, - "is_carehome": null - }, - { - "period": 9, - "household_charge": null, - "is_carehome": null + "is_carehome?": false } ] }, @@ -8602,6 +8445,12 @@ "depends_on": { "period": 1 } + }, + { + "label": " every week for 53 weeks", + "depends_on": { + "period": 10 + } } ] } diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 71d184ad6..928c8f671 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -2,5 +2,5 @@ # Configure sensitive parameters which will be filtered from the log file. Rails.application.config.filter_parameters += %i[ - passw secret token crypt salt certificate otp ssn + passw secret token crypt salt certificate otp ssn reset_password_token ] diff --git a/config/locales/en.yml b/config/locales/en.yml index e223c7fc9..eef342674 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -190,11 +190,11 @@ en: reactivating_soon: "The scheme %{name} is not available until %{date}. Select another scheme or edit the tenancy start date" activating_soon: "%{name} is not available until %{date}. Enter a tenancy start date after %{date}" owning_organisation: - invalid: "Please select owning organisation or managing organisation that you belong to" + invalid: "Please select the owning organisation or managing organisation that you belong to" managing_organisation: - invalid: "Please select owning organisation or managing organisation that you belong to" + invalid: "Please select the owning organisation or managing organisation that you belong to" created_by: - invalid: "Please select owning organisation or managing organisation that you belong to" + invalid: "Please select the owning organisation or managing organisation that you belong to" lettype: general_needs_mismatch: Lettings type must be a general needs type because you selected general needs when uploading the file supported_housing_mismatch: Lettings type must be a supported housing type because you selected supported housing when uploading the file @@ -253,10 +253,10 @@ en: freq_missing: "Select how often the household receives income" earnings_missing: "Enter how much income the household has in total" income: - over_hard_max_for_london: "Income must not exceed £90,000.00 for properties within London local authorities" - over_hard_max_for_outside_london: "Income must not exceed £80,000.00 for properties outside London local authorities" - combined_over_hard_max_for_london: "Combined income must not exceed £90,000.00 for properties within London local authorities" - combined_over_hard_max_for_outside_london: "Combined income must not exceed £80,000.00 for properties outside London local authorities" + over_hard_max_for_london: "Income must be £90,000 or lower for properties within a London local authority" + over_hard_max_for_outside_london: "Income must be £80,000 or lower for properties outside London local authority" + combined_over_hard_max_for_london: "Combined income must be £90,000 or lower for properties within a London local authority" + combined_over_hard_max_for_outside_london: "Combined income must be £80,000 or lower for properties outside London local authorities" child_has_income: "Child's income must be £0" negative_currency: "Enter an amount above 0" rent: @@ -283,7 +283,7 @@ en: general_needs: "Enter a value for the support charge between £0 and £60 per week if the landlord is a local authority and it is a general needs letting" supported_housing: "Enter a value for the support charge between £0 and £120 per week if the landlord is a local authority and it is a supported housing letting" ecstat: - over_hard_max: "Net income of £%{hard_max} per week is too high for given the tenant’s working situation" + over_hard_max: "Net income of %{hard_max} per week is too high given the tenant’s working situation" brent: below_hard_min: "Rent is below the absolute minimum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms" @@ -314,7 +314,7 @@ en: charges: complete_1_of_3: "Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’" tcharge: - under_10: "Enter a total charge that is at least £10 per week" + under_10: "Enter a total charge that is at least £10.00 per week" rent_period: invalid_for_org: "%{org_name} does not charge rent %{rent_period}" carehome: @@ -466,6 +466,7 @@ en: during_deactivated_period: "The scheme is already deactivated during this date, please enter a different date" owning_organisation: does_not_own_stock: "Enter an organisation that owns housing stock" + no_completed_locations: "This scheme cannot be chosen as it has no completed locations" location: postcode_blank: "Enter a postcode" @@ -516,8 +517,8 @@ en: under_soft_min_for_economic_status: "You said income was %{income}, which is below this working situation's minimum (%{minimum})" rent: outside_range_title: "You told us the rent is %{brent}" - min_hint_text: "The minimum rent expected for this type of property in this local authority is £%{soft_min_for_period}." - max_hint_text: "The maximum rent expected for this type of property in this local authority is £%{soft_max_for_period}." + min_hint_text: "The minimum rent expected for this type of property in this local authority is %{soft_min_for_period}." + max_hint_text: "The maximum rent expected for this type of property in this local authority is %{soft_max_for_period}." purchase_price: title_text: "You told us the purchase price is %{value}" hint_text: "The %{min_or_max} purchase price expected for this type of property in this local authority is %{soft_min_or_soft_max}" @@ -539,7 +540,7 @@ en: void_date: title_text: "You told us the time between the start of the tenancy and the void date is more than 2 years" shared_ownership_deposit: - title_text: "Mortgage, deposit and cash discount total should equal £%{expected_shared_ownership_deposit_value}" + title_text: "Mortgage, deposit and cash discount total should equal %{expected_shared_ownership_deposit_value}" old_persons_shared_ownership: "At least one buyer should be aged over 64 for Older persons’ shared ownership scheme" staircase_bought_seems_high: "You said %{percentage}% was bought in this staircasing transaction, which seems high. Are you sure?" monthly_charges_over_soft_max: @@ -547,10 +548,16 @@ en: student_not_child: title_text: "You told us this person is a student aged beween 16 and 19" discounted_sale_value: - title_text: "Mortgage, deposit, and grant total must equal £%{value_with_discount}" - informative_text: "Your given mortgage, deposit and grant total is £%{mortgage_deposit_and_grant_total}" + title_text: "Mortgage, deposit, and grant total must equal %{value_with_discount}" + informative_text: "Your given mortgage, deposit and grant total is %{mortgage_deposit_and_grant_total}" care_home_charges: title_text: "Care home charges should be provided if this is a care home accommodation" + buyer1_livein_wrong_for_ownership_type: + title_text: "You told us that buyer 1 will not live in the property. For %{ownership_scheme} types, the buyer usually lives in the property." + buyer2_livein_wrong_for_ownership_type: + title_text: "You told us that buyer 2 will not live in the property. For %{ownership_scheme} types, the buyer usually lives in the property." + percentage_discount_value: + title_text: "You told us that the percentage discount was %{discount}. This seems high for this type of property." devise: two_factor_authentication: diff --git a/config/routes.rb b/config/routes.rb index c01f38027..f6e00083b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -119,6 +119,7 @@ Rails.application.routes.draw do get "managing-agents/remove", to: "organisation_relationships#remove_managing_agent" post "managing-agents", to: "organisation_relationships#create_managing_agent" delete "managing-agents", to: "organisation_relationships#delete_managing_agent" + get "merge", to: "organisations#merge" end end diff --git a/db/migrate/20230405074138_add_percentage_discount_value_check.rb b/db/migrate/20230405074138_add_percentage_discount_value_check.rb new file mode 100644 index 000000000..adce0fe58 --- /dev/null +++ b/db/migrate/20230405074138_add_percentage_discount_value_check.rb @@ -0,0 +1,5 @@ +class AddPercentageDiscountValueCheck < ActiveRecord::Migration[7.0] + def change + add_column :sales_logs, :percentage_discount_value_check, :integer + end +end diff --git a/db/migrate/20230405140343_add_buyer_livin_value_check.rb b/db/migrate/20230405140343_add_buyer_livin_value_check.rb new file mode 100644 index 000000000..feafc610b --- /dev/null +++ b/db/migrate/20230405140343_add_buyer_livin_value_check.rb @@ -0,0 +1,5 @@ +class AddBuyerLivinValueCheck < ActiveRecord::Migration[7.0] + def change + add_column :sales_logs, :buyer_livein_value_check, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 53dbf448b..12dfe0481 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -573,6 +573,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_04_12_143245) do t.integer "nationalbuy2" t.integer "discounted_sale_value_check" t.integer "student_not_child_value_check" + t.integer "buyer_livein_value_check" + t.integer "percentage_discount_value_check" 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/public/files/bulk-upload-lettings-specification-2023-24.xlsx b/public/files/bulk-upload-lettings-specification-2023-24.xlsx index 819fdaee0..6d964c8dd 100644 Binary files a/public/files/bulk-upload-lettings-specification-2023-24.xlsx and b/public/files/bulk-upload-lettings-specification-2023-24.xlsx differ diff --git a/public/files/bulk-upload-lettings-template-2023-24.xlsx b/public/files/bulk-upload-lettings-template-2023-24.xlsx index e97e67d25..e2c6cc27f 100644 Binary files a/public/files/bulk-upload-lettings-template-2023-24.xlsx and b/public/files/bulk-upload-lettings-template-2023-24.xlsx differ diff --git a/public/files/bulk-upload-sales-specification-2023-24.xlsx b/public/files/bulk-upload-sales-specification-2023-24.xlsx index d1927d275..a7122e397 100644 Binary files a/public/files/bulk-upload-sales-specification-2023-24.xlsx and b/public/files/bulk-upload-sales-specification-2023-24.xlsx differ diff --git a/public/files/bulk-upload-sales-template-2023-24.xlsx b/public/files/bulk-upload-sales-template-2023-24.xlsx index 59fce8b6f..de79ac6d6 100644 Binary files a/public/files/bulk-upload-sales-template-2023-24.xlsx and b/public/files/bulk-upload-sales-template-2023-24.xlsx differ diff --git a/spec/components/bulk_upload_error_row_component_spec.rb b/spec/components/bulk_upload_error_row_component_spec.rb index 665a630c8..85b2fe522 100644 --- a/spec/components/bulk_upload_error_row_component_spec.rb +++ b/spec/components/bulk_upload_error_row_component_spec.rb @@ -78,22 +78,6 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do end end - context "when multiple errors for a row" do - subject(:component) { described_class.new(bulk_upload_errors:) } - - let(:bulk_upload_errors) do - [ - build(:bulk_upload_error, cell: "Z1"), - build(:bulk_upload_error, cell: "AB1"), - build(:bulk_upload_error, cell: "A1"), - ] - end - - it "is sorted by cell" do - expect(component.bulk_upload_errors.map(&:cell)).to eql(%w[A1 Z1 AB1]) - end - end - context "when a sales bulk upload" do let(:bulk_upload) { create(:bulk_upload, :sales) } let(:field) { :field_87 } diff --git a/spec/features/form/accessible_autocomplete_spec.rb b/spec/features/form/accessible_autocomplete_spec.rb index 15d23fe32..0ff03ec03 100644 --- a/spec/features/form/accessible_autocomplete_spec.rb +++ b/spec/features/form/accessible_autocomplete_spec.rb @@ -75,6 +75,7 @@ RSpec.describe "Accessible Autocomplete" do before do FactoryBot.create(:location, scheme:, postcode: "W6 0ST", startdate: Time.zone.local(2022, 1, 1)) FactoryBot.create(:location, scheme:, postcode: "SE6 1LB", startdate: Time.zone.local(2022, 1, 1)) + FactoryBot.create(:location, scheme:, postcode: nil, startdate: Time.zone.local(2022, 1, 1), confirmed: false) lettings_log.update!(needstype: 2) visit("/lettings-logs/#{lettings_log.id}/scheme") end @@ -87,7 +88,7 @@ RSpec.describe "Accessible Autocomplete" do it "displays appended text next to the options", js: true do find("#lettings-log-scheme-id-field").click.native.send_keys("w", "6", :down, :enter) expect(find(".autocomplete__option", visible: :hidden, text: scheme.service_name)).to be_present - expect(find("span", visible: :hidden, text: "2 locations")).to be_present + expect(find("span", visible: :hidden, text: "2 completed locations, 1 incomplete location")).to be_present end it "displays hint text under the options", js: true do diff --git a/spec/features/form/form_navigation_spec.rb b/spec/features/form/form_navigation_spec.rb index aa0223616..6fdec8366 100644 --- a/spec/features/form/form_navigation_spec.rb +++ b/spec/features/form/form_navigation_spec.rb @@ -110,7 +110,7 @@ RSpec.describe "Form Navigation" do click_button("Save and continue") click_link(text: "Back") click_link(text: "Back") - expect(page).to have_current_path("/lettings-logs") + expect(page).to have_current_path("/lettings-logs/#{id}") end context "when changing an answer from the check answers page", js: true do diff --git a/spec/features/organisation_spec.rb b/spec/features/organisation_spec.rb index bc6aa243a..7e25fe933 100644 --- a/spec/features/organisation_spec.rb +++ b/spec/features/organisation_spec.rb @@ -40,7 +40,7 @@ RSpec.describe "User Features" do expect(page).to have_current_path("/organisations/#{org_id}/details") end - context "when the user is a coordinator and the organisation does not hold housing stock" do + context "and the organisation does not hold housing stock" do before do organisation.update(holds_own_stock: false) end @@ -51,7 +51,7 @@ RSpec.describe "User Features" do end end - context "when the user is a coordinator and the organisation holds housing stock" do + context "and the organisation holds housing stock" do before do organisation.update(holds_own_stock: true) end @@ -61,18 +61,6 @@ RSpec.describe "User Features" do expect(page).to have_link("Schemes", href: "/schemes") end end - - context "when the user is support and the organisation does not hold housing stock" do - before do - organisation.update!(holds_own_stock: false) - user.update!(role: "support") - end - - it "does not show schemes in the primary or secondary navigation bar on the organisations page" do - visit("/organisations") - expect(page).not_to have_link("Schemes", href: "/schemes", count: 2) - end - end end context "when users are part of organisation" do @@ -321,5 +309,16 @@ RSpec.describe "User Features" do end end end + + context "and the organisation does not hold housing stock" do + before do + organisation.update!(holds_own_stock: false) + end + + it "does not show schemes in the primary or secondary navigation bar on the organisations page" do + visit("/organisations") + expect(page).not_to have_link("Schemes", href: "/schemes", count: 2) + end + end end end diff --git a/spec/fixtures/forms/2021_2022.json b/spec/fixtures/forms/2021_2022.json index ec13bdabb..97999d8a3 100644 --- a/spec/fixtures/forms/2021_2022.json +++ b/spec/fixtures/forms/2021_2022.json @@ -879,23 +879,26 @@ "4": { "value": "Every calendar month" }, - "5": { - "value": "Weekly for 50 weeks" + "9": { + "value": "Weekly for 46 weeks" }, - "6": { - "value": "Weekly for 49 weeks" + "8": { + "value": "Weekly for 47 weeks" }, "7": { "value": "Weekly for 48 weeks" }, - "8": { - "value": "Weekly for 47 weeks" + "6": { + "value": "Weekly for 49 weeks" }, - "9": { - "value": "Weekly for 46 weeks" + "5": { + "value": "Weekly for 50 weeks" }, "1": { "value": "Weekly for 52 weeks" + }, + "10": { + "value": "Weekly for 53 weeks" } } }, diff --git a/spec/helpers/collection_time_helper_spec.rb b/spec/helpers/collection_time_helper_spec.rb index 1537926ab..e9ec52292 100644 --- a/spec/helpers/collection_time_helper_spec.rb +++ b/spec/helpers/collection_time_helper_spec.rb @@ -50,7 +50,7 @@ RSpec.describe CollectionTimeHelper do let(:now) { Time.utc(2022, 8, 3) } it "returns the same year as the current start year" do - expect(collection_start_year(now)).to eq(2022) + expect(collection_start_year_for_date(now)).to eq(2022) end it "returns the correct current start date" do @@ -66,7 +66,7 @@ RSpec.describe CollectionTimeHelper do let(:now) { Time.utc(2022, 2, 3) } it "returns the previous year as the current start year" do - expect(collection_start_year(now)).to eq(2021) + expect(collection_start_year_for_date(now)).to eq(2021) end it "returns the correct current start date" do diff --git a/spec/helpers/interruption_screen_helper_spec.rb b/spec/helpers/interruption_screen_helper_spec.rb index fba8782da..33553f39f 100644 --- a/spec/helpers/interruption_screen_helper_spec.rb +++ b/spec/helpers/interruption_screen_helper_spec.rb @@ -4,9 +4,9 @@ RSpec.describe InterruptionScreenHelper do form_handler = FormHandler.instance let(:form) { form_handler.get_form("test_form") } let(:subsection) { form.get_subsection("household_characteristics") } - let(:user) { FactoryBot.create(:user) } + let(:user) { create(:user) } let(:lettings_log) do - FactoryBot.create( + create( :lettings_log, :in_progress, ecstat1: 1, @@ -14,6 +14,7 @@ RSpec.describe InterruptionScreenHelper do incfreq: 1, created_by: user, sex1: "F", + brent: 12_345, ) end @@ -45,7 +46,13 @@ RSpec.describe InterruptionScreenHelper do ], } expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("soft_validations.net_income.hint_text", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase, earnings: lettings_log.form.get_question("earnings", lettings_log).answer_label(lettings_log))) + .to eq( + I18n.t( + "soft_validations.net_income.hint_text", + ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase, + earnings: lettings_log.form.get_question("earnings", lettings_log).answer_label(lettings_log), + ), + ) end end @@ -62,7 +69,12 @@ RSpec.describe InterruptionScreenHelper do ], } expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("test.one_argument", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) + .to eq( + I18n.t( + "test.one_argument", + ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase, + ), + ) end end @@ -84,7 +96,12 @@ RSpec.describe InterruptionScreenHelper do ], } expect(display_informative_text(informative_text, lettings_log)) - .to eq(I18n.t("test.one_argument", ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) + .to eq( + I18n.t( + "test.one_argument", + ecstat1: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase, + ), + ) end end @@ -126,15 +143,15 @@ RSpec.describe InterruptionScreenHelper do informative_text_hash = { "arguments" => [ { - "key" => "retirement_age_for_person", - "arguments_for_key" => 1, + "key" => "field_formatted_as_currency", + "arguments_for_key" => "brent", "i18n_template" => "argument", }, ], } - allow(lettings_log).to receive(:retirement_age_for_person) + allow(lettings_log).to receive(:field_formatted_as_currency) display_informative_text(informative_text_hash, lettings_log) - expect(lettings_log).to have_received(:retirement_age_for_person).with(1) + expect(lettings_log).to have_received(:field_formatted_as_currency).with("brent") end it "returns the correct text" do @@ -143,13 +160,13 @@ RSpec.describe InterruptionScreenHelper do "translation" => translation, "arguments" => [ { - "key" => "retirement_age_for_person", - "arguments_for_key" => 1, + "key" => "field_formatted_as_currency", + "arguments_for_key" => "brent", "i18n_template" => "argument", }, ], } - expect(display_informative_text(informative_text_hash, lettings_log)).to eq(I18n.t(translation, argument: lettings_log.retirement_age_for_person(1))) + expect(display_informative_text(informative_text_hash, lettings_log)).to eq("You said this: £12,345.00") end end end @@ -178,6 +195,38 @@ RSpec.describe InterruptionScreenHelper do expect(display_title_text(title_text, lettings_log)) .to eq(I18n.t("test.title_text.one_argument", argument: lettings_log.form.get_question("ecstat1", lettings_log).answer_label(lettings_log).downcase)) end + + context "when and argument is given with a key and arguments for the key" do + it "makes the correct method call" do + title_text = { + "arguments" => [ + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "brent", + "i18n_template" => "argument", + }, + ], + } + allow(lettings_log).to receive(:field_formatted_as_currency) + display_title_text(title_text, lettings_log) + expect(lettings_log).to have_received(:field_formatted_as_currency).with("brent") + end + + it "returns the correct text" do + translation = "test.title_text.one_argument" + title_text = { + "translation" => translation, + "arguments" => [ + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "brent", + "i18n_template" => "argument", + }, + ], + } + expect(display_title_text(title_text, lettings_log)).to eq("You said this: £12,345.00") + end + end end context "when title text is not defined" do diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index 7926854ec..354b948d4 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/spec/helpers/locations_helper_spec.rb @@ -178,7 +178,7 @@ RSpec.describe LocationsHelper do context "when location has no local authority" do before do LocalAuthorityLink.create!(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) - location.update!(location_code: nil) + location.update!(location_code: nil, confirmed: false) end it "returns correct display attributes" do diff --git a/spec/models/form/lettings/pages/max_rent_value_check_spec.rb b/spec/models/form/lettings/pages/max_rent_value_check_spec.rb new file mode 100644 index 000000000..7a3a5544f --- /dev/null +++ b/spec/models/form/lettings/pages/max_rent_value_check_spec.rb @@ -0,0 +1,37 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::MaxRentValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { "shared_ownership_deposit_value_check" } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[rent_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("max_rent_value_check") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "rent_in_soft_max_range?" => true }]) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ "arguments" => [{ "i18n_template" => "brent", "key" => "brent", "label" => true }], "translation" => "soft_validations.rent.outside_range_title" }) + end + + it "has the correct informative_text" do + expect(page.informative_text).to eq({ "arguments" => [{ "arguments_for_key" => "soft_max_for_period", "i18n_template" => "soft_max_for_period", "key" => "field_formatted_as_currency" }], "translation" => "soft_validations.rent.max_hint_text" }) + end +end diff --git a/spec/models/form/lettings/pages/min_rent_value_check_spec.rb b/spec/models/form/lettings/pages/min_rent_value_check_spec.rb new file mode 100644 index 000000000..4e68a09c7 --- /dev/null +++ b/spec/models/form/lettings/pages/min_rent_value_check_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::MinRentValueCheck, type: :model do + subject(:page) { described_class.new(nil, page_definition, subsection) } + + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has the correct header" do + expect(page.header).to be nil + end + + it "has the correct description" do + expect(page.description).to be nil + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[rent_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("min_rent_value_check") + end + + it "has correct depends_on" do + expect(page.depends_on).to eq( + [{ "rent_in_soft_min_range?" => true }], + ) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ + "translation" => "soft_validations.rent.outside_range_title", + "arguments" => [{ "i18n_template" => "brent", "key" => "brent", "label" => true }], + }) + end + + it "has the correct informative_text" do + expect(page.informative_text).to eq({ + "arguments" => [{ "arguments_for_key" => "soft_min_for_period", "i18n_template" => "soft_min_for_period", "key" => "field_formatted_as_currency" }], + "translation" => "soft_validations.rent.min_hint_text", + }) + end +end diff --git a/spec/models/form/lettings/pages/net_income_value_check_spec.rb b/spec/models/form/lettings/pages/net_income_value_check_spec.rb new file mode 100644 index 000000000..c43eb3381 --- /dev/null +++ b/spec/models/form/lettings/pages/net_income_value_check_spec.rb @@ -0,0 +1,40 @@ +require "rails_helper" + +RSpec.describe Form::Lettings::Pages::NetIncomeValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { "shared_ownership_deposit_value_check" } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[net_income_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("net_income_value_check") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "net_income_soft_validation_triggered?" => true }]) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ "translation" => "soft_validations.net_income.title_text" }) + end + + it "has the correct informative_text" do + expect(page.informative_text).to eq({ + "arguments" => [{ "arguments_for_key" => "ecstat1", "i18n_template" => "ecstat1", "key" => "field_formatted_as_currency" }, { "arguments_for_key" => "earnings", "i18n_template" => "earnings", "key" => "field_formatted_as_currency" }], + "translation" => "soft_validations.net_income.hint_text", + }) + end +end diff --git a/spec/models/form/lettings/pages/uprn_known_spec.rb b/spec/models/form/lettings/pages/uprn_known_spec.rb deleted file mode 100644 index 27b893a5c..000000000 --- a/spec/models/form/lettings/pages/uprn_known_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require "rails_helper" - -RSpec.describe Form::Lettings::Pages::UprnKnown, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } - - let(:page_id) { nil } - let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection) } - - it "has correct subsection" do - expect(page.subsection).to eq(subsection) - end - - it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[uprn_known]) - end - - it "has the correct id" do - expect(page.id).to eq("uprn_known") - end - - it "has the correct header" do - expect(page.header).to be_nil - end - - it "has the correct description" do - expect(page.description).to be_nil - end - - it "has correct depends_on" do - expect(page.depends_on).to be_nil - end - - describe "has correct routed_to?" do - context "when needstype != 2" do - let(:log) { create(:lettings_log, needstype: nil) } - - it "returns true" do - expect(page.routed_to?(log)).to eq(true) - end - end - - context "when needstype == 2" do - let(:log) { create(:lettings_log, needstype: 2) } - - it "returns true" do - expect(page.routed_to?(log)).to eq(false) - end - end - end -end diff --git a/spec/models/form/lettings/pages/uprn_spec.rb b/spec/models/form/lettings/pages/uprn_spec.rb index 7b480b6b2..d7ddec73f 100644 --- a/spec/models/form/lettings/pages/uprn_spec.rb +++ b/spec/models/form/lettings/pages/uprn_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Form::Lettings::Pages::Uprn, type: :model do end it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[uprn]) + expect(page.questions.map(&:id)).to eq(%w[uprn_known uprn]) end it "has the correct id" do @@ -36,14 +36,6 @@ RSpec.describe Form::Lettings::Pages::Uprn, type: :model do end describe "has correct routed_to?" do - context "when uprn_known != 1" do - let(:log) { create(:lettings_log, uprn_known: 0) } - - it "returns false" do - expect(page.routed_to?(log)).to eq(false) - end - end - context "when uprn_known == 1" do let(:log) { create(:lettings_log, uprn_known: 1) } diff --git a/spec/models/form/lettings/questions/address_line1_spec.rb b/spec/models/form/lettings/questions/address_line1_spec.rb index e2600f0cc..2c13aef48 100644 --- a/spec/models/form/lettings/questions/address_line1_spec.rb +++ b/spec/models/form/lettings/questions/address_line1_spec.rb @@ -64,7 +64,7 @@ RSpec.describe Form::Lettings::Questions::AddressLine1, type: :model do end end - context "when la is present but inferred" do + context "when la is present and inferred" do let(:log) { create(:lettings_log, la: "E09000003") } before do diff --git a/spec/models/form/lettings/questions/location_id_spec.rb b/spec/models/form/lettings/questions/location_id_spec.rb index afb39ce11..fbe580970 100644 --- a/spec/models/form/lettings/questions/location_id_spec.rb +++ b/spec/models/form/lettings/questions/location_id_spec.rb @@ -48,11 +48,13 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do context "when getting available locations" do let(:scheme) { FactoryBot.create(:scheme) } let!(:lettings_log) do - FactoryBot.create(:lettings_log, owning_organisation: scheme.owning_organisation, scheme:, needstype: 2) + FactoryBot.create(:lettings_log, owning_organisation: scheme.owning_organisation, needstype: 2) end context "when there are no locations" do - it "the displayed_answer_options is an empty hash" do + it "the displayed_answer_options is an empty hash (the scheme should have failed validation anyway so don't validate here)" do + lettings_log.scheme = scheme + lettings_log.save!(validate: false) expect(question.displayed_answer_options(lettings_log)).to eq({}) end end @@ -70,6 +72,7 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do before do FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 13)) FactoryBot.create(:location, scheme:, startdate: Time.utc(2023, 1, 1)) + lettings_log.update!(scheme:) end it "the displayed_answer_options is an empty hash" do @@ -77,10 +80,11 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do end end - context "and the locations have a no startdate" do + context "and the locations have no startdate" do before do FactoryBot.create(:location, scheme:, startdate: nil) FactoryBot.create(:location, scheme:, startdate: nil) + lettings_log.update!(scheme:) end it "the displayed_answer_options shows the locations" do @@ -92,6 +96,7 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do before do FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 4, 10)) FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12)) + lettings_log.update!(scheme:) end it "the displayed_answer_options shows the locations" do @@ -103,9 +108,22 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do before do FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 10, 10)) FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12)) + lettings_log.update!(scheme:) end - it "the displayed_answer_options shows the active location" do + it "the displayed_answer_options shows only the active location" do + expect(question.displayed_answer_options(lettings_log).count).to eq(1) + end + end + + context "and some locations are not confirmed" do + before do + FactoryBot.create(:location, scheme:, postcode: nil) + FactoryBot.create(:location, scheme:) + lettings_log.update!(scheme:) + end + + it "the displayed_answer_options shows only the confirmed location" do expect(question.displayed_answer_options(lettings_log).count).to eq(1) end end diff --git a/spec/models/form/lettings/questions/scheme_id_spec.rb b/spec/models/form/lettings/questions/scheme_id_spec.rb index 7e88e3139..0b7c8da96 100644 --- a/spec/models/form/lettings/questions/scheme_id_spec.rb +++ b/spec/models/form/lettings/questions/scheme_id_spec.rb @@ -39,6 +39,45 @@ RSpec.describe Form::Lettings::Questions::SchemeId, type: :model do expect(question.derived?).to be false end + it "has the correct inferred_answers" do + expect(question.inferred_answers).to eq({ + "location.name": { + "scheme_has_multiple_locations?": false, + }, + }) + end + + describe "has the correct get_extra_check_answer_value" do + let(:scheme) { create(:scheme) } + + context "when locations are present but not inferred" do + let(:lettings_log) { create(:lettings_log) } + + before do + allow(lettings_log).to receive(:scheme_has_multiple_locations?).and_return(true) + end + + it "returns nil" do + expect(question.get_extra_check_answer_value(lettings_log)).to be_nil + end + end + + context "when location is present and inferred" do + let!(:location) { create(:location, scheme:) } + let!(:lettings_log) { create(:lettings_log, scheme:, location:) } + let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } + + before do + allow(lettings_log).to receive(:scheme_has_multiple_locations?).and_return(false) + allow(lettings_log).to receive(:form).and_return(real_2022_2023_form) + end + + it "returns the postcode" do + expect(question.get_extra_check_answer_value(lettings_log)).to eq(location.postcode) + end + end + end + context "when a user is signed in" do let(:organisation) { FactoryBot.create(:organisation) } let(:organisation_2) { FactoryBot.create(:organisation) } @@ -84,13 +123,17 @@ RSpec.describe Form::Lettings::Questions::SchemeId, type: :model do end context "when the question is answered" do - it "returns 'select an option' as selected answer" do + before do + FactoryBot.create(:location, scheme:) + end + + it "returns scheme as selected answer" do lettings_log.update!(scheme:) answers = question.displayed_answer_options(lettings_log).map do |key, value| OpenStruct.new(id: key, name: value.respond_to?(:service_name) ? value.service_name : nil, resource: value) end answers.each do |answer| - if answer.id == scheme.id + if answer.id.to_i == scheme.id expect(question.answer_selected?(lettings_log, answer)).to eq(true) else expect(question.answer_selected?(lettings_log, answer)).to eq(false) diff --git a/spec/models/form/lettings/questions/uprn_known_spec.rb b/spec/models/form/lettings/questions/uprn_known_spec.rb index 07eb72f8d..a79185462 100644 --- a/spec/models/form/lettings/questions/uprn_known_spec.rb +++ b/spec/models/form/lettings/questions/uprn_known_spec.rb @@ -39,7 +39,7 @@ RSpec.describe Form::Lettings::Questions::UprnKnown, type: :model do end it "has correct conditional for" do - expect(question.conditional_for).to be_nil + expect(question.conditional_for).to eq({ "uprn" => [1] }) end it "has the correct unanswered_error_message" do @@ -54,6 +54,6 @@ RSpec.describe Form::Lettings::Questions::UprnKnown, type: :model do end it "has the correct hidden_in_check_answers" do - expect(question.hidden_in_check_answers).to be_nil + expect(question.hidden_in_check_answers).to eq(true) end end diff --git a/spec/models/form/lettings/questions/uprn_spec.rb b/spec/models/form/lettings/questions/uprn_spec.rb index 8f6ba047a..5e0be655b 100644 --- a/spec/models/form/lettings/questions/uprn_spec.rb +++ b/spec/models/form/lettings/questions/uprn_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do end it "has the correct hint" do - expect(question.hint_text).to eq("The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.") + expect(question.hint_text).to be_nil end it "has the correct unanswered_error_message" do @@ -61,32 +61,44 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do county: "Test County", postcode_full: "AA1 1AA", la: "E09000003", + uprn_known:, ) end - it "returns formatted value" do - expect(question.get_extra_check_answer_value(log)).to eq( - "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster", - ) + context "when uprn known nil" do + let(:uprn_known) { nil } + + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end end - end - end - describe "has the correct hidden_in_check_answers" do - context "when uprn_known == 1" do - let(:log) { create(:lettings_log, uprn_known: 1) } + context "when uprn known" do + let(:uprn_known) { 1 } - it "returns false" do - expect(question.hidden_in_check_answers?(log)).to eq(false) + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to eq( + "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster", + ) + end end - end - context "when uprn_known != 1" do - let(:log) { create(:lettings_log, uprn_known: 0) } + context "when uprn not known" do + let(:uprn_known) { 0 } - it "returns false" do - expect(question.hidden_in_check_answers?(log)).to eq(true) + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end end end end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([{ + "condition" => { + "uprn_known" => 0, + }, + "value" => "Not known", + }]) + end end diff --git a/spec/models/form/lettings/subsections/property_information_spec.rb b/spec/models/form/lettings/subsections/property_information_spec.rb index b66761125..0eac3a27a 100644 --- a/spec/models/form/lettings/subsections/property_information_spec.rb +++ b/spec/models/form/lettings/subsections/property_information_spec.rb @@ -49,7 +49,6 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do it "has correct pages" do expect(property_information.pages.map(&:id)).to eq( %w[ - uprn_known uprn uprn_confirmation address diff --git a/spec/models/form/sales/pages/about_price_value_check_spec.rb b/spec/models/form/sales/pages/about_price_value_check_spec.rb new file mode 100644 index 000000000..6c8d27463 --- /dev/null +++ b/spec/models/form/sales/pages/about_price_value_check_spec.rb @@ -0,0 +1,54 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::AboutPriceValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { "savings_value_check" } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[value_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("savings_value_check") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([{ "purchase_price_out_of_soft_range?" => true }]) + end + + it "is interruption screen page" do + expect(page.interruption_screen?).to eq(true) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ "arguments" => [{ "i18n_template" => "value", "key" => "value", "label" => true }], "translation" => "soft_validations.purchase_price.title_text" }) + end + + it "has the correct informative_text" do + expect(page.informative_text).to eq({ + "translation" => "soft_validations.purchase_price.hint_text", + "arguments" => [ + { + "key" => "field_formatted_as_currency", + "arguments_for_key" => "purchase_price_soft_min_or_soft_max", + "i18n_template" => "soft_min_or_soft_max", + }, + { + "key" => "purchase_price_min_or_max_text", + "i18n_template" => "min_or_max", + }, + ], + }) + end +end diff --git a/spec/models/form/sales/pages/buyer_live_in_value_check_spec.rb b/spec/models/form/sales/pages/buyer_live_in_value_check_spec.rb new file mode 100644 index 000000000..9d00b086b --- /dev/null +++ b/spec/models/form/sales/pages/buyer_live_in_value_check_spec.rb @@ -0,0 +1,64 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::BuyerLiveInValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection, person_index:) } + + let(:page_id) { "buyer_1_live_in_value_check" } + let(:page_definition) { nil } + let(:person_index) { 1 } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[buyer_livein_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("buyer_1_live_in_value_check") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([ + { + "buyer1_livein_wrong_for_ownership_type?" => true, + }, + ]) + end + + it "is interruption screen page" do + expect(page.interruption_screen?).to eq(true) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ + "translation" => "soft_validations.buyer1_livein_wrong_for_ownership_type.title_text", + "arguments" => [{ "key" => "ownership_scheme", "label" => false, "i18n_template" => "ownership_scheme" }], + }) + end + + context "with buyer 2" do + let(:person_index) { 2 } + + it "has correct depends_on" do + expect(page.depends_on).to eq([ + { + "buyer2_livein_wrong_for_ownership_type?" => true, + }, + ]) + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ + "translation" => "soft_validations.buyer2_livein_wrong_for_ownership_type.title_text", + "arguments" => [{ "key" => "ownership_scheme", "label" => false, "i18n_template" => "ownership_scheme" }], + }) + end + end +end diff --git a/spec/models/form/sales/pages/discounted_sale_value_check_spec.rb b/spec/models/form/sales/pages/discounted_sale_value_check_spec.rb index ddd4bc33c..d086542dc 100644 --- a/spec/models/form/sales/pages/discounted_sale_value_check_spec.rb +++ b/spec/models/form/sales/pages/discounted_sale_value_check_spec.rb @@ -27,14 +27,14 @@ RSpec.describe Form::Sales::Pages::DiscountedSaleValueCheck, type: :model do it "has the correct title_text" do expect(page.title_text).to eq({ "translation" => "soft_validations.discounted_sale_value.title_text", - "arguments" => [{ "key" => "value_with_discount", "label" => false, "i18n_template" => "value_with_discount" }], + "arguments" => [{ "arguments_for_key" => "value_with_discount", "i18n_template" => "value_with_discount", "key" => "field_formatted_as_currency" }], }) end it "has the correct informative_text" do expect(page.informative_text).to eq({ "translation" => "soft_validations.discounted_sale_value.informative_text", - "arguments" => [{ "key" => "mortgage_deposit_and_grant_total", "label" => false, "i18n_template" => "mortgage_deposit_and_grant_total" }], + "arguments" => [{ "arguments_for_key" => "mortgage_deposit_and_grant_total", "i18n_template" => "mortgage_deposit_and_grant_total", "key" => "field_formatted_as_currency" }], }) end diff --git a/spec/models/form/sales/pages/percentage_discount_value_check_spec.rb b/spec/models/form/sales/pages/percentage_discount_value_check_spec.rb new file mode 100644 index 000000000..d933e3278 --- /dev/null +++ b/spec/models/form/sales/pages/percentage_discount_value_check_spec.rb @@ -0,0 +1,48 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Pages::PercentageDiscountValueCheck, type: :model do + subject(:page) { described_class.new(page_id, page_definition, subsection) } + + let(:page_id) { "percentage_discount_value_check" } + let(:page_definition) { nil } + let(:subsection) { instance_double(Form::Subsection) } + + it "has correct subsection" do + expect(page.subsection).to eq(subsection) + end + + it "has correct questions" do + expect(page.questions.map(&:id)).to eq(%w[percentage_discount_value_check]) + end + + it "has the correct id" do + expect(page.id).to eq("percentage_discount_value_check") + end + + it "has the correct header" do + expect(page.header).to be_nil + end + + it "has the correct title_text" do + expect(page.title_text).to eq({ + "translation" => "soft_validations.percentage_discount_value.title_text", + "arguments" => [{ "key" => "discount", "label" => true, "i18n_template" => "discount" }], + }) + end + + it "has the correct informative_text" do + expect(page.informative_text).to eq({}) + end + + it "is interruption screen page" do + expect(page.interruption_screen?).to eq(true) + end + + it "has correct depends_on" do + expect(page.depends_on).to eq([ + { + "percentage_discount_invalid?" => true, + }, + ]) + end +end diff --git a/spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb b/spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb index 893a5cb5b..45744cde4 100644 --- a/spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb +++ b/spec/models/form/sales/pages/shared_ownership_deposit_value_check_spec.rb @@ -34,13 +34,7 @@ RSpec.describe Form::Sales::Pages::SharedOwnershipDepositValueCheck, type: :mode it "has the correct title_text" do expect(page.title_text).to eq({ "translation" => "soft_validations.shared_ownership_deposit.title_text", - "arguments" => [ - { - "key" => "expected_shared_ownership_deposit_value", - "label" => false, - "i18n_template" => "expected_shared_ownership_deposit_value", - }, - ], + "arguments" => [{ "arguments_for_key" => "expected_shared_ownership_deposit_value", "i18n_template" => "expected_shared_ownership_deposit_value", "key" => "field_formatted_as_currency" }], }) end diff --git a/spec/models/form/sales/pages/uprn_known_spec.rb b/spec/models/form/sales/pages/uprn_known_spec.rb deleted file mode 100644 index 9c18cfa21..000000000 --- a/spec/models/form/sales/pages/uprn_known_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require "rails_helper" - -RSpec.describe Form::Sales::Pages::UprnKnown, type: :model do - subject(:page) { described_class.new(page_id, page_definition, subsection) } - - let(:page_id) { nil } - let(:page_definition) { nil } - let(:subsection) { instance_double(Form::Subsection) } - - it "has correct subsection" do - expect(page.subsection).to eq(subsection) - end - - it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[uprn_known]) - end - - it "has the correct id" do - expect(page.id).to eq("uprn_known") - end - - it "has the correct header" do - expect(page.header).to be_nil - end - - it "has the correct description" do - expect(page.description).to be_nil - end - - it "has correct depends_on" do - expect(page.depends_on).to be_nil - end -end diff --git a/spec/models/form/sales/pages/uprn_spec.rb b/spec/models/form/sales/pages/uprn_spec.rb index 5573caf5a..a0cd5b7bc 100644 --- a/spec/models/form/sales/pages/uprn_spec.rb +++ b/spec/models/form/sales/pages/uprn_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Form::Sales::Pages::Uprn, type: :model do end it "has correct questions" do - expect(page.questions.map(&:id)).to eq(%w[uprn]) + expect(page.questions.map(&:id)).to eq(%w[uprn_known uprn]) end it "has the correct id" do diff --git a/spec/models/form/sales/questions/address_line1_spec.rb b/spec/models/form/sales/questions/address_line1_spec.rb index f037f41cd..8c73feef2 100644 --- a/spec/models/form/sales/questions/address_line1_spec.rb +++ b/spec/models/form/sales/questions/address_line1_spec.rb @@ -64,7 +64,7 @@ RSpec.describe Form::Sales::Questions::AddressLine1, type: :model do end end - context "when la is present but inferred" do + context "when la is present and inferred" do let(:log) { create(:sales_log, la: "E09000003") } before do diff --git a/spec/models/form/sales/questions/buyer_live_in_value_check_spec.rb b/spec/models/form/sales/questions/buyer_live_in_value_check_spec.rb new file mode 100644 index 000000000..0409f4f2e --- /dev/null +++ b/spec/models/form/sales/questions/buyer_live_in_value_check_spec.rb @@ -0,0 +1,62 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::BuyerLiveInValueCheck, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page, person_index:) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:person_index) { 1 } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("buyer_livein_value_check") + end + + it "has the correct header" do + expect(question.header).to eq("Are you sure this is correct?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Buyer live in confirmation") + end + + it "has the correct type" do + expect(question.type).to eq("interruption_screen") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has a correct check_answers_card_number" do + expect(question.check_answers_card_number).to eq(1) + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to eq({ + "depends_on" => [ + { + "buyer_livein_value_check" => 0, + }, + { + "buyer_livein_value_check" => 1, + }, + ], + }) + end +end diff --git a/spec/models/form/sales/questions/percentage_discount_value_check_spec.rb b/spec/models/form/sales/questions/percentage_discount_value_check_spec.rb new file mode 100644 index 000000000..72f4f0cbb --- /dev/null +++ b/spec/models/form/sales/questions/percentage_discount_value_check_spec.rb @@ -0,0 +1,57 @@ +require "rails_helper" + +RSpec.describe Form::Sales::Questions::PercentageDiscountValueCheck, type: :model do + subject(:question) { described_class.new(question_id, question_definition, page) } + + let(:question_id) { nil } + let(:question_definition) { nil } + let(:page) { instance_double(Form::Page) } + + it "has correct page" do + expect(question.page).to eq(page) + end + + it "has the correct id" do + expect(question.id).to eq("percentage_discount_value_check") + end + + it "has the correct header" do + expect(question.header).to eq("Are you sure this is correct?") + end + + it "has the correct check_answer_label" do + expect(question.check_answer_label).to eq("Percentage discount confirmation") + end + + it "has the correct type" do + expect(question.type).to eq("interruption_screen") + end + + it "is not marked as derived" do + expect(question.derived?).to be false + end + + it "has the correct hint" do + expect(question.hint_text).to be_nil + end + + it "has the correct answer_options" do + expect(question.answer_options).to eq({ + "0" => { "value" => "Yes" }, + "1" => { "value" => "No" }, + }) + end + + it "has the correct hidden_in_check_answers" do + expect(question.hidden_in_check_answers).to eq({ + "depends_on" => [ + { + "percentage_discount_value_check" => 0, + }, + { + "percentage_discount_value_check" => 1, + }, + ], + }) + end +end diff --git a/spec/models/form/sales/questions/uprn_known_spec.rb b/spec/models/form/sales/questions/uprn_known_spec.rb index 457471568..4016b6e8d 100644 --- a/spec/models/form/sales/questions/uprn_known_spec.rb +++ b/spec/models/form/sales/questions/uprn_known_spec.rb @@ -39,7 +39,7 @@ RSpec.describe Form::Sales::Questions::UprnKnown, type: :model do end it "has correct conditional for" do - expect(question.conditional_for).to be_nil + expect(question.conditional_for).to eq({ "uprn" => [1] }) end it "has the correct unanswered_error_message" do @@ -54,6 +54,6 @@ RSpec.describe Form::Sales::Questions::UprnKnown, type: :model do end it "has the correct hidden_in_check_answers" do - expect(question.hidden_in_check_answers).to be_nil + expect(question.hidden_in_check_answers).to eq(true) end end diff --git a/spec/models/form/sales/questions/uprn_spec.rb b/spec/models/form/sales/questions/uprn_spec.rb index f8fd75942..46e635868 100644 --- a/spec/models/form/sales/questions/uprn_spec.rb +++ b/spec/models/form/sales/questions/uprn_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Form::Sales::Questions::Uprn, type: :model do end it "has the correct hint" do - expect(question.hint_text).to eq("The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and sectors UK-wide. For example 10010457355.") + expect(question.hint_text).to be_nil end it "has the correct unanswered_error_message" do @@ -61,33 +61,44 @@ RSpec.describe Form::Sales::Questions::Uprn, type: :model do county: "Test County", postcode_full: "AA1 1AA", la: "E09000003", + uprn_known:, ) end - it "returns formatted value" do - expect(question.get_extra_check_answer_value(log)).to eq( - "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster", - ) + context "when uprn known nil" do + let(:uprn_known) { nil } + + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end end - end - end - describe "has the correct hidden_in_check_answers" do - context "when uprn_known == 1" do - let(:log) { create(:sales_log) } + context "when uprn known" do + let(:uprn_known) { 1 } - it "returns false" do - log.uprn_known = 1 - expect(question.hidden_in_check_answers?(log)).to eq(false) + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to eq( + "\n\n1, Test Street\nTest Town\nTest County\nAA1 1AA\nWestminster", + ) + end end - end - context "when uprn_known != 1" do - let(:log) { create(:sales_log, uprn_known: 0) } + context "when uprn not known" do + let(:uprn_known) { 0 } - it "returns false" do - expect(question.hidden_in_check_answers?(log)).to eq(true) + it "returns formatted value" do + expect(question.get_extra_check_answer_value(log)).to be_nil + end end end end + + it "has the correct inferred_check_answers_value" do + expect(question.inferred_check_answers_value).to eq([{ + "condition" => { + "uprn_known" => 0, + }, + "value" => "Not known", + }]) + end end diff --git a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb index 5c0dbfea0..9aa0aa102 100644 --- a/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb +++ b/spec/models/form/sales/subsections/discounted_ownership_scheme_spec.rb @@ -17,6 +17,7 @@ RSpec.describe Form::Sales::Subsections::DiscountedOwnershipScheme, type: :model living_before_purchase_discounted_ownership about_price_rtb extra_borrowing_price_value_check + percentage_discount_value_check about_price_not_rtb grant_value_check purchase_price_discounted_ownership diff --git a/spec/models/form/sales/subsections/household_characteristics_spec.rb b/spec/models/form/sales/subsections/household_characteristics_spec.rb index 57a9ce019..c926baa08 100644 --- a/spec/models/form/sales/subsections/household_characteristics_spec.rb +++ b/spec/models/form/sales/subsections/household_characteristics_spec.rb @@ -39,6 +39,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_1_retirement_value_check working_situation_buyer_1_income_value_check buyer_1_live_in_property + buyer_1_live_in_property_value_check buyer_2_relationship_to_buyer_1 buyer_2_relationship_student_not_child_value_check buyer_2_age @@ -52,6 +53,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_buyer_2_income_value_check buyer_2_working_situation_student_not_child_value_check buyer_2_live_in_property + buyer_2_live_in_property_value_check number_of_others_in_property number_of_others_in_property_joint_purchase person_2_known @@ -141,6 +143,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_1_retirement_value_check working_situation_buyer_1_income_value_check buyer_1_live_in_property + buyer_1_live_in_property_value_check buyer_2_relationship_to_buyer_1 buyer_2_relationship_student_not_child_value_check buyer_2_age @@ -161,6 +164,7 @@ RSpec.describe Form::Sales::Subsections::HouseholdCharacteristics, type: :model working_situation_buyer_2_income_value_check buyer_2_working_situation_student_not_child_value_check buyer_2_live_in_property + buyer_2_live_in_property_value_check number_of_others_in_property number_of_others_in_property_joint_purchase person_2_known diff --git a/spec/models/form/sales/subsections/property_information_spec.rb b/spec/models/form/sales/subsections/property_information_spec.rb index 1c049ea97..559db5ea6 100644 --- a/spec/models/form/sales/subsections/property_information_spec.rb +++ b/spec/models/form/sales/subsections/property_information_spec.rb @@ -24,6 +24,7 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do about_price_bedrooms_value_check property_unit_type monthly_charges_property_type_value_check + percentage_discount_proptype_value_check property_building_type property_postcode property_local_authority @@ -40,7 +41,6 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do it "has correct pages" do expect(property_information.pages.map(&:id)).to eq( %w[ - uprn_known uprn uprn_confirmation address @@ -49,6 +49,7 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do about_price_bedrooms_value_check property_unit_type monthly_charges_property_type_value_check + percentage_discount_proptype_value_check property_building_type about_price_la_value_check property_wheelchair_accessible diff --git a/spec/models/form/sales/subsections/setup_spec.rb b/spec/models/form/sales/subsections/setup_spec.rb index 92271ba25..7f12a8498 100644 --- a/spec/models/form/sales/subsections/setup_spec.rb +++ b/spec/models/form/sales/subsections/setup_spec.rb @@ -26,6 +26,8 @@ RSpec.describe Form::Sales::Subsections::Setup, type: :model do ownership_type_old_persons_shared_ownership_value_check monthly_charges_type_value_check discounted_sale_type_value_check + buyer_1_live_in_property_type_value_check + buyer_2_live_in_property_type_value_check buyer_company buyer_live joint_purchase diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index e3123ad41..908fcab17 100644 --- a/spec/models/form_spec.rb +++ b/spec/models/form_spec.rb @@ -17,11 +17,11 @@ RSpec.describe Form, type: :model do let(:conditional_section_complete_lettings_log) { FactoryBot.build(:lettings_log, :conditional_section_complete) } describe ".next_page" do - let(:previous_page) { form.get_page("person_1_age") } + let(:previous_page_id) { form.get_page("person_1_age") } let(:value_check_previous_page) { form.get_page("net_income_value_check") } it "returns the next page given the previous" do - expect(form.next_page(previous_page, lettings_log, user)).to eq("person_1_gender") + expect(form.next_page_id(previous_page_id, lettings_log, user)).to eq("person_1_gender") end context "when the current page is a value check page" do @@ -33,12 +33,12 @@ RSpec.describe Form, type: :model do it "returns the previous page if answer is `No` and the page is routed to" do lettings_log.net_income_value_check = 1 - expect(form.next_page(value_check_previous_page, lettings_log, user)).to eq("net_income") + expect(form.next_page_id(value_check_previous_page, lettings_log, user)).to eq("net_income") end it "returns the next page if answer is `Yes` answer and the page is routed to" do lettings_log.net_income_value_check = 0 - expect(form.next_page(value_check_previous_page, lettings_log, user)).to eq("net_income_uc_proportion") + expect(form.next_page_id(value_check_previous_page, lettings_log, user)).to eq("net_income_uc_proportion") end end end @@ -46,31 +46,30 @@ RSpec.describe Form, type: :model do describe ".previous_page" do context "when the current page is not a value check page" do let!(:subsection) { form.get_subsection("conditional_question") } - let!(:page_ids) { subsection.pages.map(&:id) } before do lettings_log.preg_occ = 2 end it "returns the previous page if the page is routed to" do - page_index = page_ids.index("conditional_question_no_second_page") - expect(form.previous_page(page_ids, page_index, lettings_log, user)).to eq("conditional_question_no_page") + page = subsection.pages.find { |p| p.id == "conditional_question_no_second_page" } + expect(form.previous_page_id(page, lettings_log, user)).to eq("conditional_question_no_page") end it "returns the page before the previous one if the previous page is not routed to" do - page_index = page_ids.index("conditional_question_no_page") - expect(form.previous_page(page_ids, page_index, lettings_log, user)).to eq("conditional_question") + page = subsection.pages.find { |p| p.id == "conditional_question_no_page" } + expect(form.previous_page_id(page, lettings_log, user)).to eq("conditional_question") end end end describe "next_page_redirect_path" do - let(:previous_page) { form.get_page("net_income") } + let(:previous_page_id) { form.get_page("net_income") } let(:last_previous_page) { form.get_page("housing_benefit") } let(:previous_conditional_page) { form.get_page("conditional_question") } it "returns a correct page path if there is no conditional routing" do - expect(form.next_page_redirect_path(previous_page, lettings_log, user)).to eq("lettings_log_net_income_uc_proportion_path") + expect(form.next_page_redirect_path(previous_page_id, lettings_log, user)).to eq("lettings_log_net_income_uc_proportion_path") end it "returns a check answers page if previous page is the last page" do @@ -247,9 +246,9 @@ RSpec.describe Form, type: :model do expect(form.sections[0].class).to eq(Form::Sales::Sections::Setup) expect(form.subsections.count).to eq(1) expect(form.subsections.first.id).to eq("setup") - expect(form.pages.count).to eq(16) + expect(form.pages.count).to eq(18) expect(form.pages.first.id).to eq("organisation") - expect(form.questions.count).to eq(17) + expect(form.questions.count).to eq(19) expect(form.questions.first.id).to eq("owning_organisation_id") expect(form.start_date).to eq(Time.zone.parse("2022-04-01")) expect(form.end_date).to eq(Time.zone.parse("2023-06-07")) diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index ea771af6b..c7968b9ee 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -1,13 +1,13 @@ require "rails_helper" require "shared/shared_examples_for_derived_fields" +# rubocop:disable RSpec/MessageChain # rubocop:disable RSpec/AnyInstance RSpec.describe LettingsLog do let(:different_managing_organisation) { create(:organisation) } let(:created_by_user) { create(:user) } let(:owning_organisation) { created_by_user.organisation } let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - let(:fake_2022_2023_form) { Form.new("spec/fixtures/forms/2022_2023.json") } around do |example| Timecop.freeze(Time.utc(2022, 1, 1)) do @@ -1084,6 +1084,87 @@ RSpec.describe LettingsLog do expect(record_from_db["wtcharge"]).to eq(187.2) end end + + context "when rent is paid weekly for 53 weeks" do + it "correctly derives and saves weekly rent" do + lettings_log.update!(brent: 130, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wrent from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wrent).to eq(132.5) + expect(record_from_db["wrent"]).to eq(132.5) + end + + it "correctly derives and saves weekly service charge" do + lettings_log.update!(scharge: 30, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wscharge from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wscharge).to eq(30.58) + expect(record_from_db["wscharge"]).to eq(30.58) + end + + it "correctly derives and saves weekly personal service charge" do + lettings_log.update!(pscharge: 30, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wpschrge from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wpschrge).to eq(30.58) + expect(record_from_db["wpschrge"]).to eq(30.58) + end + + it "correctly derives and saves weekly support charge" do + lettings_log.update!(supcharg: 30, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wsupchrg from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wsupchrg).to eq(30.58) + expect(record_from_db["wsupchrg"]).to eq(30.58) + end + + it "correctly derives and saves weekly total charge" do + lettings_log.update!(tcharge: 30, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wtcharge from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wtcharge).to eq(30.58) + expect(record_from_db["wtcharge"]).to eq(30.58) + end + + context "when the tenant has an outstanding amount after benefits" do + context "when tenant is in receipt of housing benefit" do + it "correctly derives and saves weekly total shortfall" do + lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 1) + record_from_db = ActiveRecord::Base.connection.execute("select wtshortfall from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wtshortfall).to eq(132.5) + expect(record_from_db["wtshortfall"]).to eq(132.5) + end + end + + context "when tenant is in receipt of universal credit with housing element exc. housing benefit" do + it "correctly derives and saves weekly total shortfall" do + lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 6) + record_from_db = ActiveRecord::Base.connection.execute("select wtshortfall from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wtshortfall).to eq(132.5) + expect(record_from_db["wtshortfall"]).to eq(132.5) + end + end + + context "when tenant is in receipt of housing benefit and universal credit" do + it "correctly derives and saves weekly total shortfall" do + lettings_log.update!(hbrentshortfall: 1, tshortfall: 130, period: 10, hb: 8) + record_from_db = ActiveRecord::Base.connection.execute("select wtshortfall from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wtshortfall).to eq(132.5) + expect(record_from_db["wtshortfall"]).to eq(132.5) + end + end + end + + it "correctly derives floats" do + lettings_log.update!(supcharg: 30.12, pscharge: 25.13, scharge: 30.98, brent: 100.97, period: 10) + record_from_db = ActiveRecord::Base.connection.execute("select wtcharge, wsupchrg, wpschrge, wscharge, wrent from lettings_logs where id=#{lettings_log.id}").to_a[0] + expect(lettings_log.wsupchrg).to eq(30.7) + expect(lettings_log.wpschrge).to eq(25.61) + expect(lettings_log.wscharge).to eq(31.58) + expect(lettings_log.wrent).to eq(102.91) + expect(lettings_log.wtcharge).to eq(190.8) + expect(record_from_db["wsupchrg"]).to eq(30.7) + expect(record_from_db["wpschrge"]).to eq(25.61) + expect(record_from_db["wscharge"]).to eq(31.58) + expect(record_from_db["wrent"]).to eq(102.91) + expect(record_from_db["wtcharge"]).to eq(190.8) + end + end end context "when the owning organisation is a LA" do @@ -2264,7 +2345,7 @@ RSpec.describe LettingsLog do describe "resetting invalidated fields" do let(:scheme) { create(:scheme, owning_organisation: created_by_user.organisation) } - let(:location) { create(:location, location_code: "E07000223", scheme:) } + let!(:location) { create(:location, location_code: "E07000223", scheme:) } let(:lettings_log) do create( :lettings_log, @@ -3065,6 +3146,7 @@ RSpec.describe LettingsLog do .and change(lettings_log, :postcode_full).from(nil).to("POSTCODE") .and change(lettings_log, :uprn_confirmed).from(1).to(nil) .and change(lettings_log, :county).from("county").to(nil) + .and change(lettings_log, :uprn_known).from(nil).to(1) end end @@ -3114,5 +3196,55 @@ RSpec.describe LettingsLog do end end end + + describe "#collection_period_open?" do + let(:log) { build(:lettings_log, startdate:) } + + context "when startdate is nil" do + let(:startdate) { nil } + + it "returns false" do + expect(log.collection_period_open?).to eq(true) + end + end + + context "when older_than_previous_collection_year" do + let(:previous_collection_start_date) { Time.zone.local(2050, 4, 1) } + let(:startdate) { previous_collection_start_date - 1.day } + + before do + allow(log).to receive(:previous_collection_start_date).and_return(previous_collection_start_date) + end + + it "returns true" do + expect(log.collection_period_open?).to eq(false) + end + end + + context "when form end date is in the future" do + let(:startdate) { nil } + + before do + allow(log).to receive_message_chain(:form, :end_date).and_return(Time.zone.now + 1.day) + end + + it "returns true" do + expect(log.collection_period_open?).to eq(true) + end + end + + context "when form end date is in the past" do + let(:startdate) { Time.zone.local(2020, 4, 1) } + + before do + allow(log).to receive_message_chain(:form, :end_date).and_return(Time.zone.now - 1.day) + end + + it "returns false" do + expect(log.collection_period_open?).to eq(false) + end + end + end end # rubocop:enable RSpec/AnyInstance +# rubocop:enable RSpec/MessageChain diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 3d10ec777..1fe359136 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -788,7 +788,7 @@ RSpec.describe Location, type: :model do before do FactoryBot.create(:location, name: "ABC", postcode: "NW1 8RR", startdate: Time.zone.today) FactoryBot.create(:location, name: "XYZ", postcode: "SE1 6HJ", startdate: Time.zone.today + 1.day) - FactoryBot.create(:location, name: "GHQ", postcode: "EW1 7JK", startdate: Time.zone.today - 1.day, units: nil) + FactoryBot.create(:location, name: "GHQ", postcode: "EW1 7JK", startdate: Time.zone.today - 1.day, units: nil, confirmed: false) FactoryBot.create(:location, name: "GHQ", postcode: "EW1 7JK", startdate: nil) end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 0632af547..c008269ea 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -1,6 +1,7 @@ require "rails_helper" require "shared/shared_examples_for_derived_fields" +# rubocop:disable RSpec/MessageChain # rubocop:disable RSpec/AnyInstance RSpec.describe SalesLog, type: :model do let(:owning_organisation) { create(:organisation) } @@ -61,6 +62,7 @@ RSpec.describe SalesLog, type: :model do old_persons_shared_ownership_value_check othtype discounted_sale_value_check + buyer_livein_value_check proplen mortlen frombeds @@ -79,6 +81,7 @@ RSpec.describe SalesLog, type: :model do old_persons_shared_ownership_value_check othtype discounted_sale_value_check + buyer_livein_value_check address_line2 county postcode_full @@ -498,7 +501,7 @@ RSpec.describe SalesLog, type: :model do let!(:completed_sales_log) { create(:sales_log, :completed, ownershipsch: 1, type: 2, value: 1000, equity: 50) } it "is set to completed for a completed sales log" do - expect(completed_sales_log.expected_shared_ownership_deposit_value).to eq("£500.00") + expect(completed_sales_log.expected_shared_ownership_deposit_value).to eq(500) end end @@ -556,6 +559,7 @@ RSpec.describe SalesLog, type: :model do .and change(sales_log, :postcode_full).from(nil).to("POSTCODE") .and change(sales_log, :uprn_confirmed).from(1).to(nil) .and change(sales_log, :county).from("county").to(nil) + .and change(sales_log, :uprn_known).from(nil).to(1) end end @@ -605,5 +609,55 @@ RSpec.describe SalesLog, type: :model do end end end + + describe "#collection_period_open?" do + let(:log) { build(:sales_log, saledate:) } + + context "when saledate is nil" do + let(:saledate) { nil } + + it "returns false" do + expect(log.collection_period_open?).to eq(true) + end + end + + context "when older_than_previous_collection_year" do + let(:previous_collection_start_date) { Time.zone.local(2050, 4, 1) } + let(:saledate) { previous_collection_start_date - 1.day } + + before do + allow(log).to receive(:previous_collection_start_date).and_return(previous_collection_start_date) + end + + it "returns true" do + expect(log.collection_period_open?).to eq(false) + end + end + + context "when form end date is in the future" do + let(:saledate) { nil } + + before do + allow(log).to receive_message_chain(:form, :end_date).and_return(Time.zone.now + 1.day) + end + + it "returns true" do + expect(log.collection_period_open?).to eq(true) + end + end + + context "when form end date is in the past" do + let(:saledate) { Time.zone.local(2020, 4, 1) } + + before do + allow(log).to receive_message_chain(:form, :end_date).and_return(Time.zone.now - 1.day) + end + + it "returns false" do + expect(log.collection_period_open?).to eq(false) + end + end + end end # rubocop:enable RSpec/AnyInstance +# rubocop:enable RSpec/MessageChain diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb index 239be2853..b9c747e9c 100644 --- a/spec/models/validations/date_validations_spec.rb +++ b/spec/models/validations/date_validations_spec.rb @@ -4,9 +4,9 @@ RSpec.describe Validations::DateValidations do subject(:date_validator) { validator_class.new } let(:validator_class) { Class.new { include Validations::DateValidations } } - let(:record) { FactoryBot.create(:lettings_log) } - let(:scheme) { FactoryBot.create(:scheme, end_date: Time.zone.today - 5.days) } - let(:scheme_no_end_date) { FactoryBot.create(:scheme, end_date: nil) } + let(:record) { create(:lettings_log) } + let(:scheme) { create(:scheme, end_date: Time.zone.today - 5.days) } + let(:scheme_no_end_date) { create(:scheme, end_date: nil) } describe "tenancy start date" do it "must be a valid date" do @@ -165,7 +165,7 @@ RSpec.describe Validations::DateValidations do let(:scheme) { create(:scheme) } before do - FactoryBot.create(:location, scheme:) + create(:location, scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:) scheme.reload end @@ -190,7 +190,7 @@ RSpec.describe Validations::DateValidations do let(:scheme) { create(:scheme) } before do - FactoryBot.create(:location, scheme:) + create(:location, scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 2), reactivation_date: Time.zone.local(2022, 8, 3), scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 1), reactivation_date: Time.zone.local(2022, 9, 4), scheme:) diff --git a/spec/models/validations/sales/soft_validations_spec.rb b/spec/models/validations/sales/soft_validations_spec.rb index 712e53965..f63f6fbcc 100644 --- a/spec/models/validations/sales/soft_validations_spec.rb +++ b/spec/models/validations/sales/soft_validations_spec.rb @@ -913,4 +913,325 @@ RSpec.describe Validations::Sales::SoftValidations do end end end + + describe "#buyer1_livein_wrong_for_ownership_type?" do + context "when it's a shared ownership" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 1) } + + context "and buy1livein is no" do + before do + record.buy1livein = 2 + end + + it "returns true" do + expect(record).to be_buyer1_livein_wrong_for_ownership_type + end + end + + context "and buy1livein is yes" do + before do + record.buy1livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer1_livein_wrong_for_ownership_type + end + end + end + end + + describe "#percentage_discount_invalid?" do + context "when property type is Flat (1)" do + let(:record) { FactoryBot.build(:sales_log, proptype: 1) } + + context "and discount is under 50%" do + before do + record.discount = 49 + end + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "and discount is over 50%" do + before do + record.discount = 51 + end + + it "returns true" do + expect(record).to be_percentage_discount_invalid + end + end + end + + context "when it's a discounted ownership" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 2) } + + context "and buy1livein is no" do + before do + record.buy1livein = 2 + end + + it "returns true" do + expect(record).to be_buyer1_livein_wrong_for_ownership_type + end + end + + context "and buy1livein is yes" do + before do + record.buy1livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer1_livein_wrong_for_ownership_type + end + end + end + + context "when property type is masionette or bedsit (2)" do + let(:record) { FactoryBot.build(:sales_log, proptype: 2) } + + context "and discount is under 50%" do + before do + record.discount = 49 + end + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "and discount is over 50%" do + before do + record.discount = 51 + end + + it "returns true" do + expect(record).to be_percentage_discount_invalid + end + end + end + + context "when it's a outright sale" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 3) } + + context "and buy1livein is no" do + before do + record.buy1livein = 2 + end + + it "returns false" do + expect(record).not_to be_buyer1_livein_wrong_for_ownership_type + end + end + + context "and buy1livein is yes" do + before do + record.buy1livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer1_livein_wrong_for_ownership_type + end + end + end + + context "when property type is House (3)" do + let(:record) { FactoryBot.build(:sales_log, proptype: 3) } + + context "and discount is under 35%" do + before do + record.discount = 34 + end + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "and discount is over 35%" do + before do + record.discount = 36 + end + + it "returns true" do + expect(record).to be_percentage_discount_invalid + end + end + end + + context "when ownership is not given" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 3) } + + before do + record.ownershipsch = nil + end + + it "returns false" do + expect(record).not_to be_buyer1_livein_wrong_for_ownership_type + end + end + end + + describe "#buyer2_livein_wrong_for_ownership_type?" do + context "when it's a shared ownership" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 1, jointpur: 1) } + + context "and buy2livein is no" do + before do + record.buy2livein = 2 + end + + it "returns true" do + expect(record).to be_buyer2_livein_wrong_for_ownership_type + end + end + + context "and buy2livein is yes" do + before do + record.buy2livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + + context "and not a joint purchase" do + before do + record.buy2livein = 2 + record.jointpur = 2 + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + end + + context "when it's a discounted ownership" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 2, jointpur: 1) } + + context "and buy2livein is no" do + before do + record.buy2livein = 2 + end + + it "returns true" do + expect(record).to be_buyer2_livein_wrong_for_ownership_type + end + end + + context "and buy2livein is yes" do + before do + record.buy2livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + end + + context "when it's a outright sale" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 3, jointpur: 1) } + + context "and buy2livein is no" do + before do + record.buy2livein = 2 + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + + context "and buy2livein is yes" do + before do + record.buy2livein = 1 + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + end + + context "when ownership is not given" do + let(:record) { FactoryBot.build(:sales_log, ownershipsch: 3, jointpur: 1) } + + before do + record.ownershipsch = nil + end + + it "returns false" do + expect(record).not_to be_buyer2_livein_wrong_for_ownership_type + end + end + + context "when property type is Bungalow (4)" do + let(:record) { FactoryBot.build(:sales_log, proptype: 4) } + + context "and discount is under 35%" do + before do + record.discount = 34 + end + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "and discount is over 35%" do + before do + record.discount = 36 + end + + it "returns true" do + expect(record).to be_percentage_discount_invalid + end + end + end + + context "when property type is Other (9)" do + let(:record) { FactoryBot.build(:sales_log, proptype: 9) } + + context "and discount is under 35%" do + before do + record.discount = 34 + end + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "and discount is over 35%" do + before do + record.discount = 36 + end + + it "returns true" do + expect(record).to be_percentage_discount_invalid + end + end + end + + context "when discount is not given" do + let(:record) { FactoryBot.build(:sales_log, proptype: 1, discount: nil) } + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + + context "when property type is not given" do + let(:record) { FactoryBot.build(:sales_log, proptype: nil, discount: 51) } + + it "returns false" do + expect(record).not_to be_percentage_discount_invalid + end + end + end end diff --git a/spec/models/validations/setup_validations_spec.rb b/spec/models/validations/setup_validations_spec.rb index 16d52fb07..5bb180aa2 100644 --- a/spec/models/validations/setup_validations_spec.rb +++ b/spec/models/validations/setup_validations_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Validations::SetupValidations do subject(:setup_validator) { setup_validator_class.new } let(:setup_validator_class) { Class.new { include Validations::SetupValidations } } - let(:record) { FactoryBot.create(:lettings_log) } + let(:record) { create(:lettings_log) } describe "tenancy start date" do context "when in 22/23 collection" do @@ -188,7 +188,7 @@ RSpec.describe Validations::SetupValidations do let(:scheme) { create(:scheme, created_at: Time.zone.local(2022, 4, 1)) } before do - FactoryBot.create(:location, scheme:) + create(:location, scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:) scheme.reload end @@ -213,7 +213,7 @@ RSpec.describe Validations::SetupValidations do let(:scheme) { create(:scheme, created_at: Time.zone.local(2022, 4, 1)) } before do - FactoryBot.create(:location, scheme:) + create(:location, scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), reactivation_date: Time.zone.local(2022, 8, 4), scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 2), reactivation_date: Time.zone.local(2022, 8, 3), scheme:) create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 1), reactivation_date: Time.zone.local(2022, 9, 4), scheme:) @@ -310,8 +310,8 @@ RSpec.describe Validations::SetupValidations do end describe "#validate_organisation" do - let(:user) { FactoryBot.create(:user) } - let(:other_organisation) { FactoryBot.create(:organisation) } + let(:user) { create(:user) } + let(:other_organisation) { create(:organisation) } it "validates if neither managing nor owning organisation is the same as created_by user organisation" do record.created_by = user @@ -368,4 +368,36 @@ RSpec.describe Validations::SetupValidations do expect(record.errors["managing_organisation_id"]).to be_empty end end + + describe "#validate_scheme_has_confirmed_locations_validation" do + let(:scheme) { create(:scheme) } + + context "with a scheme that has no confirmed locations" do + before do + create(:location, scheme:, postcode: nil) + scheme.reload + end + + it "produces an error" do + record.scheme = scheme + setup_validator.validate_scheme_has_confirmed_locations_validation(record) + expect(record.errors["scheme_id"]) + .to include(match I18n.t("validations.scheme.no_completed_locations")) + end + end + + context "with a scheme that has confirmed locations" do + before do + create(:location, scheme:) + scheme.reload + end + + it "does not produce an error" do + record.scheme = scheme + setup_validator.validate_scheme_has_confirmed_locations_validation(record) + expect(record.errors["scheme_id"]) + .to be_empty + end + end + end end diff --git a/spec/requests/form_controller_spec.rb b/spec/requests/form_controller_spec.rb index c60448e4e..de2e0b571 100644 --- a/spec/requests/form_controller_spec.rb +++ b/spec/requests/form_controller_spec.rb @@ -201,25 +201,27 @@ RSpec.describe FormController, type: :request do describe "GET" do context "with form pages" do - context "when forms exist for multiple years" do - let(:lettings_log_year_1) { create(:lettings_log, owning_organisation: organisation, created_by: user) } - let(:lettings_log_year_2) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } + context "when forms exist" do + let(:lettings_log) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } - before do - Timecop.freeze(Time.zone.local(2021, 5, 1)) - lettings_log_year_1.update!(startdate: Time.zone.local(2021, 5, 1)) - Timecop.unfreeze - allow(lettings_log_year_1.form).to receive(:end_date).and_return(Time.zone.today + 1.day) - end + it "displays the question details" do + get "/lettings-logs/#{lettings_log.id}/tenant-code-test", headers: headers, params: {} - it "displays the correct question details for each lettings log based on form year" do - get "/lettings-logs/#{lettings_log_year_1.id}/tenant-code-test", headers: headers, params: {} - expect(response.body).to include("What is the tenant code?") - get "/lettings-logs/#{lettings_log_year_2.id}/tenant-code-test", headers: headers, params: {} + expect(response).to be_ok expect(response.body).to match("Different question header text for this year - 2023") end end + context "when question not routed to" do + let(:lettings_log) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } + + it "redirects to log" do + get "/lettings-logs/#{lettings_log.id}/scheme", headers: headers, params: {} + + expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}") + end + end + context "when lettings logs are not owned or managed by your organisation" do it "does not show form pages for lettings logs you don't have access to" do get "/lettings-logs/#{unauthorized_lettings_log.id}/person-1-age", headers: headers, params: {} diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 154d18735..ab9dcd268 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -1263,14 +1263,30 @@ RSpec.describe LocationsController, type: :request do patch "/schemes/#{scheme.id}/locations/#{location.id}/confirm", params: end - it "confirms location" do - expect(Location.last.confirmed).to eq(true) + context "when location is complete" do + it "confirms location" do + expect(Location.last.confirmed).to eq(true) + end + + it "redirects correctly and displays success banner" do + follow_redirect! + expect(page).to have_content("Success") + expect(page).to have_content("added to this scheme") + end end - it "redirects correctly and displays success banner" do - follow_redirect! - expect(page).to have_content("Success") - expect(page).to have_content("added to this scheme") + context "when location is not complete" do + let(:location) { FactoryBot.create(:location, scheme:, startdate: Time.zone.local(2000, 1, 1), postcode: nil) } + + it "does not confirm location" do + expect(Location.last.confirmed).to eq(false) + end + + it "redirects correctly and does not display success banner" do + follow_redirect! + expect(page).not_to have_content("Success") + expect(page).not_to have_content("added to this scheme") + end end end @@ -1308,14 +1324,30 @@ RSpec.describe LocationsController, type: :request do patch "/schemes/#{scheme.id}/locations/#{location.id}/confirm", params: end - it "confirms location" do - expect(Location.last.confirmed).to eq(true) + context "when location is complete" do + it "confirms location" do + expect(Location.last.confirmed).to eq(true) + end + + it "redirects correctly and displays success banner" do + follow_redirect! + expect(page).to have_content("Success") + expect(page).to have_content("added to this scheme") + end end - it "redirects correctly and displays success banner" do - follow_redirect! - expect(page).to have_content("Success") - expect(page).to have_content("added to this scheme") + context "when location is not complete" do + let(:location) { FactoryBot.create(:location, scheme:, startdate: Time.zone.local(2000, 1, 1), postcode: nil) } + + it "does not confirm location" do + expect(Location.last.confirmed).to eq(false) + end + + it "redirects correctly and does not display success banner" do + follow_redirect! + expect(page).not_to have_content("Success") + expect(page).not_to have_content("added to this scheme") + end end end diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 15cfba390..459987fdc 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -227,6 +227,11 @@ RSpec.describe OrganisationsController, type: :request do expected_html = "data-qa=\"change-name\" href=\"/organisations/#{organisation.id}/edit\"" expect(response.body).to include(expected_html) end + + it "displays a link to merge organisations" do + expect(page).to have_content("Is your organisation merging with another?") + expect(page).to have_link("Let us know using this form", href: "/organisations/#{organisation.id}/merge") + end end context "with organisation that are not in scope for the user, i.e. that they do not belong to" do @@ -435,6 +440,36 @@ RSpec.describe OrganisationsController, type: :request do expect { request }.not_to change(Organisation, :count) end end + + describe "#merge" do + context "with an organisation that the user belongs to" do + before do + get "/organisations/#{organisation.id}/merge", headers:, params: {} + end + + it "shows the correct content" do + expect(page).to have_content("Tell us if your organisation is merging") + end + + it "has a correct back link" do + expect(page).to have_link("Back", href: "/organisations/#{organisation.id}") + end + + it "has a correct start no button" do + expect(page).to have_link("Start now", href: "#") + end + end + + context "with organisation that are not in scope for the user, i.e. that they do not belong to" do + before do + get "/organisations/#{unauthorised_organisation.id}/merge", headers:, params: {} + end + + it "returns not found 404 from org details route" do + expect(response).to have_http_status(:not_found) + end + end + end end context "with a data provider user" do diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index fb9150940..1a450a922 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -658,6 +658,26 @@ RSpec.describe SchemesController, type: :request do end end + context "when scheme is completed but not yet confirmed" do + let(:params) { { scheme: { page: "check-answers" } } } + + it "is not confirmed" do + expect(scheme_to_update.confirmed).to eq(nil) + end + + context "when confirming finished scheme" do + let(:params) { { scheme: { confirmed: true, page: "check-answers" } } } + + before do + scheme_to_update.reload + end + + it "confirms scheme" do + expect(scheme_to_update.confirmed).to eq(true) + end + end + end + context "when required params are missing" do let(:params) do { scheme: { @@ -921,6 +941,35 @@ RSpec.describe SchemesController, type: :request do patch "/schemes/#{scheme_to_update.id}", params: end + context "when confirming unfinished scheme" do + let(:params) { { scheme: { owning_organisation_id: user.organisation.id, arrangement_type: nil, confirmed: true, page: "check-answers" } } } + + it "does not allow the scheme to be confirmed" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.arrangement_type.invalid")) + end + end + + context "when scheme is completed but not yet confirmed" do + let(:params) { { scheme: { page: "check-answers" } } } + + it "is not confirmed" do + expect(scheme_to_update.confirmed).to eq(nil) + end + + context "when confirming finished scheme" do + let(:params) { { scheme: { confirmed: true, page: "check-answers" } } } + + before do + scheme_to_update.reload + end + + it "confirms scheme" do + expect(scheme_to_update.confirmed).to eq(true) + end + end + end + context "when required params are missing" do let(:params) do { scheme: { diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb index b79ee9f88..37d8e24a5 100644 --- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb @@ -242,9 +242,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do let(:attributes) { { bulk_upload:, field_13: "123" } } it "has errors on setup fields" do - errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute) + errors = parser.errors.select { |e| e.options[:category] == :setup }.map(&:attribute).sort - expect(errors).to eql(%i[field_4 field_5 field_7 field_8 field_9 field_1 field_2]) + expect(errors).to eql(%i[field_1 field_2 field_4 field_5 field_6 field_7 field_8 field_9]) end end @@ -792,7 +792,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do end end - describe "#field_6" do + describe "#field_6" do # renewal context "when an unpermitted value" do let(:attributes) { { bulk_upload:, field_6: "3" } } @@ -800,6 +800,14 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do expect(parser.errors[:field_6]).to be_present end end + + context "when blank" do + let(:attributes) { { bulk_upload:, field_1: owning_org.old_visible_id, field_6: "" } } + + it "has errors on the field" do + expect(parser.errors[:field_6]).to include("You must answer property renewal") + end + end end describe "#field_18" do # UPRN @@ -844,12 +852,12 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do end end - describe "#field_56" do # age3 + describe "#field_52" do # age2 context "when null but gender given" do - let(:attributes) { setup_section_params.merge({ field_56: "", field_57: "F" }) } + let(:attributes) { setup_section_params.merge({ field_52: "", field_53: "F" }) } it "returns an error" do - expect(parser.errors[:field_56]).to be_present + expect(parser.errors[:field_52]).to be_present end end end @@ -1103,14 +1111,6 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do expect(parser.log.renewal).to eq(0) end end - - context "when field_6 is null but rsnvac/field_27 is 14" do - let(:attributes) { { bulk_upload:, field_6: "", field_27: "14" } } - - it "sets renewal to 1" do - expect(parser.log.renewal).to eq(1) - end - end end describe "#sexN fields" do diff --git a/spec/services/exports/lettings_log_export_service_spec.rb b/spec/services/exports/lettings_log_export_service_spec.rb index b2aaace1a..349d2fc84 100644 --- a/spec/services/exports/lettings_log_export_service_spec.rb +++ b/spec/services/exports/lettings_log_export_service_spec.rb @@ -135,6 +135,15 @@ RSpec.describe Exports::LettingsLogExportService do export_service.export_xml_lettings_logs end + + it "generates a master manifest with CSV headers" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\ncore_2021_2022_apr_mar_f0001_inc0001,2022-05-01 00:00:00 +0100,#{expected_zip_filename}\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml_lettings_logs + expect(actual_content).to eq(expected_content) + end end context "with 23/24 collection period" do diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb index deccde0c0..4621afb2f 100644 --- a/spec/services/imports/lettings_logs_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_import_service_spec.rb @@ -323,6 +323,34 @@ RSpec.describe Imports::LettingsLogsImportService do end end + context "and is a other tenancy but missing tenancyother" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + + before do + lettings_log_xml.at_xpath("//meta:status").content = "saved" + lettings_log_xml.at_xpath("//xmlns:Q2b").content = "3" + lettings_log_xml.at_xpath("//xmlns:Q2ba").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.tenancy).to be_nil + expect(lettings_log.tenancyother).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" @@ -532,11 +560,11 @@ RSpec.describe Imports::LettingsLogsImportService do end it "intercepts the relevant validation error" do - expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing brent with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10 per week") - expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing scharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10 per week") - expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing pscharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10 per week") - expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing supcharg with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10 per week") - expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing tcharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10 per week") + expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing brent with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing scharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing pscharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing supcharg with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0b4a68df-30cc-474a-93c0-a56ce8fdad3b: Removing tcharge with error: Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’, Enter a total charge that is at least £10.00 per week") expect { lettings_log_service.send(:create_log, lettings_log_xml) } .not_to raise_error end @@ -719,6 +747,78 @@ RSpec.describe Imports::LettingsLogsImportService do end end + context "and tcharge is less than £10 per week" do + before do + lettings_log_xml.at_xpath("//xmlns:Q18ai").content = "1" + lettings_log_xml.at_xpath("//xmlns:Q18aii").content = "2" + lettings_log_xml.at_xpath("//xmlns:Q18aiii").content = "3" + lettings_log_xml.at_xpath("//xmlns:Q18aiv").content = "3" + lettings_log_xml.at_xpath("//xmlns:Q18av").content = "9" + end + + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing brent with error: Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing scharge with error: Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing pscharge with error: Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing supcharg with error: Enter a total charge that is at least £10.00 per week") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing tcharge with error: Enter a total charge that is at least £10.00 per week") + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end + + it "clears out the charges 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.tcharge).to be_nil + end + end + + context "and rent is higher than the absolute maximum expected for a property " do + before do + LaRentRange.create!( + ranges_rent_id: "2", + la: "E08000035", + beds: 2, + lettype: 1, + soft_min: 12.41, + soft_max: 89.54, + hard_min: 9.87, + hard_max: 100.99, + start_year: 2021, + ) + + lettings_log_xml.at_xpath("//xmlns:Q18ai").content = "500" + lettings_log_xml.at_xpath("//xmlns:Q18aii").content = "2" + lettings_log_xml.at_xpath("//xmlns:Q18aiii").content = "3" + lettings_log_xml.at_xpath("//xmlns:Q18aiv").content = "3" + lettings_log_xml.at_xpath("//xmlns:Q18av").content = "508" + end + + it "intercepts the relevant validation error" do + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing brent with error: Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing scharge with error: Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing pscharge with error: Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing supcharg with error: Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms") + expect(logger).to receive(:warn).with("Log 0ead17cb-1668-442d-898c-0d52879ff592: Removing tcharge with error: Rent is higher than the absolute maximum expected for a property of this type. Please check the rent, rent period, local authority and (if general needs) number of bedrooms") + expect { lettings_log_service.send(:create_log, lettings_log_xml) } + .not_to raise_error + end + + it "clears out the charges 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.tcharge).to be_nil + end + end + context "and location is not active during the period" do let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } diff --git a/spec/views/bulk_upload_lettings_results/show.html.erb_spec.rb b/spec/views/bulk_upload_lettings_results/show.html.erb_spec.rb new file mode 100644 index 000000000..286e1e279 --- /dev/null +++ b/spec/views/bulk_upload_lettings_results/show.html.erb_spec.rb @@ -0,0 +1,20 @@ +require "rails_helper" + +RSpec.describe "bulk_upload_lettings_results/show.html.erb" do + let(:bulk_upload) { create(:bulk_upload, :lettings) } + + before do + create(:bulk_upload_error, bulk_upload:, cell: "AA100", row: "100", col: "AA") + create(:bulk_upload_error, bulk_upload:, cell: "Z100", row: "100", col: "Z") + end + + it "renders errors ordered by cell" do + assign(:bulk_upload, bulk_upload) + + render + + fragment = Capybara::Node::Simple.new(rendered) + + expect(fragment.find_css("table tbody th").map(&:inner_text)).to eql(%w[Z100 AA100]) + end +end