Browse Source

Cldc 1668 update impacted logs (#1035)

* Mark log as impacted by deactivation when location is deactivated

* Display affected logs in the table

* Route affected logs to tenancy start date question

* Update routes to get the tenancy start date page from form

* update next_page_redirect_path

* rename column

* Fix tests

* Add next_unresolved_page_id to pages

* Update unresulved when the log is corrected

* Mark logs as unresolved when scheme gets deactivated

* display correct content when there are no unresolved logs

* mark logs resolved after the user leaves check answers page

* Display link in success banner and reset banner when the link is clicked

* display inset hint text for unresolved log questions

* Display unresolved logs banner

* update banner message

* Persist the link in the banner

* update inset text

* Update success banner text

* Add unresolved and created_by scopes

* rename method

* add unresolved_log_redirect_page_id to form + typo and route

* Add UnresolvedLogHelper and extract flack notice message

* pluralize and return early

* remove flash[:notice] = nil

* to keep it consistent for sales log

* Extract unresolved path and fix a link

* extract resolve method and fix attribute nme

* update path

* typo
pull/1057/head
kosiakkatrina 2 years ago committed by GitHub
parent
commit
497f16ba9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      app/controllers/lettings_logs_controller.rb
  2. 2
      app/controllers/locations_controller.rb
  3. 2
      app/controllers/schemes_controller.rb
  4. 7
      app/helpers/unresolved_log_helper.rb
  5. 9
      app/models/form.rb
  6. 1
      app/models/form/lettings/pages/location.rb
  7. 1
      app/models/form/lettings/pages/scheme.rb
  8. 1
      app/models/form/lettings/pages/tenancy_start_date.rb
  9. 1
      app/models/form/lettings/questions/tenancy_start_date.rb
  10. 3
      app/models/form/page.rb
  11. 4
      app/models/form/question.rb
  12. 5
      app/models/lettings_log.rb
  13. 1
      app/models/log.rb
  14. 4
      app/models/sales_log.rb
  15. 2
      app/services/csv/lettings_log_csv_service.rb
  16. 4
      app/views/form/_date_question.html.erb
  17. 2
      app/views/layouts/application.html.erb
  18. 12
      app/views/logs/index.html.erb
  19. 46
      app/views/logs/update_logs.html.erb
  20. 1
      config/forms/2021_2022.json
  21. 1
      config/forms/2022_2023.json
  22. 1
      config/routes.rb
  23. 7
      db/migrate/20221125102013_add_impacted_by_deactivation_column.rb
  24. 1
      db/schema.rb
  25. 4
      spec/fixtures/files/lettings_logs_download.csv
  26. 1
      spec/fixtures/forms/2021_2022.json
  27. 1
      spec/fixtures/forms/2022_2023.json
  28. 10
      spec/models/form_spec.rb
  29. 110
      spec/requests/lettings_logs_controller_spec.rb
  30. 12
      spec/requests/locations_controller_spec.rb
  31. 12
      spec/requests/schemes_controller_spec.rb
  32. 1
      spec/services/csv/lettings_log_csv_service_spec.rb

27
app/controllers/lettings_logs_controller.rb

@ -13,6 +13,7 @@ class LettingsLogsController < LogsController
@pagy, @logs = pagy(unpaginated_filtered_logs) @pagy, @logs = pagy(unpaginated_filtered_logs)
@searched = search_term.presence @searched = search_term.presence
@total_count = all_logs.size @total_count = all_logs.size
@unresolved_count = all_logs.unresolved.created_by(current_user).count
render "logs/index" render "logs/index"
end end
end end
@ -37,6 +38,7 @@ class LettingsLogsController < LogsController
def show def show
respond_to do |format| respond_to do |format|
# We don't have a dedicated non-editable show view # We don't have a dedicated non-editable show view
resolve_logs!
format.html { edit } format.html { edit }
format.json do format.json do
if @log if @log
@ -51,7 +53,11 @@ class LettingsLogsController < LogsController
def edit def edit
@log = current_user.lettings_logs.find_by(id: params[:id]) @log = current_user.lettings_logs.find_by(id: params[:id])
if @log if @log
render "logs/edit", locals: { current_user: } if @log.unresolved
redirect_to(send(@log.form.unresolved_log_path, @log))
else
render("logs/edit", locals: { current_user: })
end
else else
render_not_found render_not_found
end end
@ -83,6 +89,18 @@ class LettingsLogsController < LogsController
def csv_confirmation; end def csv_confirmation; end
def update_logs
respond_to do |format|
format.html do
impacted_logs = current_user.lettings_logs.unresolved.created_by(current_user)
@pagy, @logs = pagy(impacted_logs)
@total_count = impacted_logs.size
render "logs/update_logs"
end
end
end
private private
def permitted_log_params def permitted_log_params
@ -96,4 +114,11 @@ private
def post_create_redirect_url(log) def post_create_redirect_url(log)
lettings_log_url(log) lettings_log_url(log)
end end
def resolve_logs!
if @log&.unresolved && @log.location.present? && @log.scheme.present? && @log&.resolve!
unresolved_logs_count_for_user = current_user.lettings_logs.unresolved.created_by(current_user).count
flash.now[:notice] = helpers.flash_notice_for_resolved_logs(unresolved_logs_count_for_user)
end
end
end end

2
app/controllers/locations_controller.rb

@ -219,7 +219,7 @@ private
end end
def reset_location_and_scheme_for_logs! def reset_location_and_scheme_for_logs!
@location.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil) @location.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil, unresolved: true)
end end
def toggle_date(key) def toggle_date(key)

2
app/controllers/schemes_controller.rb

@ -349,6 +349,6 @@ private
end end
def reset_location_and_scheme_for_logs! def reset_location_and_scheme_for_logs!
@scheme.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil) @scheme.lettings_logs.filter_by_before_startdate(params[:deactivation_date].to_time).update!(location: nil, scheme: nil, unresolved: true)
end end
end end

7
app/helpers/unresolved_log_helper.rb

@ -0,0 +1,7 @@
module UnresolvedLogHelper
def flash_notice_for_resolved_logs(count)
notice_message = "You’ve updated all the fields affected by the scheme change.</br>"
notice_message << " <a href=\"/lettings-logs/update-logs\">Update #{count} more #{'log'.pluralize(count)}</a>" if count.positive?
notice_message
end
end

9
app/models/form.rb

@ -1,7 +1,7 @@
class Form class Form
attr_reader :form_definition, :sections, :subsections, :pages, :questions, attr_reader :form_definition, :sections, :subsections, :pages, :questions,
:start_date, :end_date, :type, :name, :setup_definition, :start_date, :end_date, :type, :name, :setup_definition,
:setup_sections, :form_sections :setup_sections, :form_sections, :unresolved_log_redirect_page_id
def initialize(form_path, start_year = "", sections_in_form = [], type = "lettings") def initialize(form_path, start_year = "", sections_in_form = [], type = "lettings")
if type == "sales" if type == "sales"
@ -33,6 +33,7 @@ class Form
@questions = pages.flat_map(&:questions) @questions = pages.flat_map(&:questions)
@start_date = Time.iso8601(form_definition["start_date"]) @start_date = Time.iso8601(form_definition["start_date"])
@end_date = Time.iso8601(form_definition["end_date"]) @end_date = Time.iso8601(form_definition["end_date"])
@unresolved_log_redirect_page_id = form_definition["unresolved_log_redirect_page_id"]
end end
@name = "#{start_date.year}_#{end_date.year}_#{type}" @name = "#{start_date.year}_#{end_date.year}_#{type}"
end end
@ -56,6 +57,8 @@ class Form
end end
def next_page(page, log, current_user) def next_page(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_ids = subsection_for_page(page).pages.map(&:id)
page_index = page_ids.index(page.id) page_index = page_ids.index(page.id)
page_id = if page.id.include?("value_check") && log[page.questions[0].id] == 1 && page.routed_to?(log, current_user) page_id = if page.id.include?("value_check") && log[page.questions[0].id] == 1 && page.routed_to?(log, current_user)
@ -84,6 +87,10 @@ class Form
"#{log.class.name.underscore}_#{page.subsection.id}_check_answers_path" "#{log.class.name.underscore}_#{page.subsection.id}_check_answers_path"
end end
def unresolved_log_path
"#{type}_log_#{unresolved_log_redirect_page_id}_path"
end
def next_incomplete_section_redirect_path(subsection, log) def next_incomplete_section_redirect_path(subsection, log)
subsection_ids = subsections.map(&:id) subsection_ids = subsections.map(&:id)

1
app/models/form/lettings/pages/location.rb

@ -7,6 +7,7 @@ class Form::Lettings::Pages::Location < ::Form::Page
"needstype" => 2, "needstype" => 2,
"scheme_has_multiple_locations?" => true, "scheme_has_multiple_locations?" => true,
}] }]
@next_unresolved_page_id = :check_answers
end end
def questions def questions

1
app/models/form/lettings/pages/scheme.rb

@ -6,6 +6,7 @@ class Form::Lettings::Pages::Scheme < ::Form::Page
@depends_on = [{ @depends_on = [{
"needstype" => 2, "needstype" => 2,
}] }]
@next_unresolved_page_id = "location"
end end
def questions def questions

1
app/models/form/lettings/pages/tenancy_start_date.rb

@ -4,6 +4,7 @@ class Form::Lettings::Pages::TenancyStartDate < ::Form::Page
@id = "tenancy_start_date" @id = "tenancy_start_date"
@description = "" @description = ""
@subsection = subsection @subsection = subsection
@next_unresolved_page_id = "scheme"
end end
def questions def questions

1
app/models/form/lettings/questions/tenancy_start_date.rb

@ -5,6 +5,7 @@ class Form::Lettings::Questions::TenancyStartDate < ::Form::Question
@check_answer_label = "Tenancy start date" @check_answer_label = "Tenancy start date"
@header = "What is the tenancy start date?" @header = "What is the tenancy start date?"
@type = "date" @type = "date"
@unresolved_hint_text = "Some scheme details have changed, and now this log needs updating. Check that the tenancy start date is correct."
@page = page @page = page
end end
end end

3
app/models/form/page.rb

@ -1,6 +1,6 @@
class Form::Page class Form::Page
attr_accessor :id, :header, :header_partial, :description, :questions, :depends_on, :title_text, attr_accessor :id, :header, :header_partial, :description, :questions, :depends_on, :title_text,
:informative_text, :subsection, :hide_subsection_label :informative_text, :subsection, :hide_subsection_label, :next_unresolved_page_id
def initialize(id, hsh, subsection) def initialize(id, hsh, subsection)
@id = id @id = id
@ -14,6 +14,7 @@ class Form::Page
@title_text = hsh["title_text"] @title_text = hsh["title_text"]
@informative_text = hsh["informative_text"] @informative_text = hsh["informative_text"]
@hide_subsection_label = hsh["hide_subsection_label"] @hide_subsection_label = hsh["hide_subsection_label"]
@next_unresolved_page_id = hsh["next_unresolved_page_id"]
end end
end end

4
app/models/form/question.rb

@ -3,7 +3,8 @@ class Form::Question
:type, :min, :max, :step, :width, :fields_to_add, :result_field, :type, :min, :max, :step, :width, :fields_to_add, :result_field,
:conditional_for, :readonly, :answer_options, :page, :check_answer_label, :conditional_for, :readonly, :answer_options, :page, :check_answer_label,
:inferred_answers, :hidden_in_check_answers, :inferred_check_answers_value, :inferred_answers, :hidden_in_check_answers, :inferred_check_answers_value,
:guidance_partial, :prefix, :suffix, :requires_js, :fields_added, :derived, :check_answers_card_number :guidance_partial, :prefix, :suffix, :requires_js, :fields_added, :derived,
:check_answers_card_number, :unresolved_hint_text
module GuidancePosition module GuidancePosition
TOP = 1 TOP = 1
@ -38,6 +39,7 @@ class Form::Question
@requires_js = hsh["requires_js"] @requires_js = hsh["requires_js"]
@fields_added = hsh["fields_added"] @fields_added = hsh["fields_added"]
@check_answers_card_number = hsh["check_answers_card_number"] || 0 @check_answers_card_number = hsh["check_answers_card_number"] || 0
@unresolved_hint_text = hsh["unresolved_hint_text"]
end end
end end

5
app/models/lettings_log.rb

@ -46,6 +46,7 @@ class LettingsLog < Log
.or(filter_by_id(param)) .or(filter_by_id(param))
} }
scope :filter_by_before_startdate, ->(date) { where("lettings_logs.startdate >= ?", date) } scope :filter_by_before_startdate, ->(date) { where("lettings_logs.startdate >= ?", date) }
scope :unresolved, -> { where(unresolved: true) }
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze
OPTIONAL_FIELDS = %w[first_time_property_let_as_social_housing tenancycode propcode].freeze OPTIONAL_FIELDS = %w[first_time_property_let_as_social_housing tenancycode propcode].freeze
@ -512,6 +513,10 @@ class LettingsLog < Log
[needstype, renewal, rent_type, startdate, owning_organisation_id, created_by_id].all?(&:present?) [needstype, renewal, rent_type, startdate, owning_organisation_id, created_by_id].all?(&:present?)
end end
def resolve!
update(unresolved: false)
end
private private
PIO = PostcodeService.new PIO = PostcodeService.new

1
app/models/log.rb

@ -23,6 +23,7 @@ class Log < ApplicationRecord
where(created_by: user) where(created_by: user)
end end
} }
scope :created_by, ->(user) { where(created_by: user) }
def collection_start_year def collection_start_year
return @start_year if @start_year return @start_year if @start_year

4
app/models/sales_log.rb

@ -56,4 +56,8 @@ class SalesLog < Log
def setup_completed? def setup_completed?
form.setup_sections.all? { |sections| sections.subsections.all? { |subsection| subsection.status(self) == :completed } } form.setup_sections.all? { |sections| sections.subsections.all? { |subsection| subsection.status(self) == :completed } }
end end
def unresolved
false
end
end end

2
app/services/csv/lettings_log_csv_service.rb

@ -1,6 +1,6 @@
module Csv module Csv
class LettingsLogCsvService class LettingsLogCsvService
CSV_FIELDS_TO_OMIT = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc].freeze CSV_FIELDS_TO_OMIT = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc unresolved].freeze
def initialize(user) def initialize(user)
@user = user @user = user

4
app/views/form/_date_question.html.erb

@ -5,6 +5,8 @@
legend: legend(question, page_header, conditional), legend: legend(question, page_header, conditional),
hint: { text: question.hint_text&.html_safe || "For example, 1 9 2022." }, hint: { text: question.hint_text&.html_safe || "For example, 1 9 2022." },
width: 20, width: 20,
**stimulus_html_attributes(question) %> **stimulus_html_attributes(question) do %>
<%= govuk_inset_text(text: question.unresolved_hint_text) if question.unresolved_hint_text.present? && @log.unresolved %>
<% end %>
<%= render partial: "form/guidance/#{question.guidance_partial}" if question.bottom_guidance? %> <%= render partial: "form/guidance/#{question.guidance_partial}" if question.bottom_guidance? %>

2
app/views/layouts/application.html.erb

@ -124,7 +124,7 @@
success: true, title_heading_level: 3, success: true, title_heading_level: 3,
title_id: "swanky-notifications" title_id: "swanky-notifications"
) do |notification_banner| ) do |notification_banner|
notification_banner.heading(text: flash.notice) notification_banner.heading(text: flash.notice.html_safe)
end %> end %>
<% end %> <% end %>
<%= content_for?(:content) ? yield(:content) : yield %> <%= content_for?(:content) ? yield(:content) : yield %>

12
app/views/logs/index.html.erb

@ -4,6 +4,18 @@
<% content_for :title, title %> <% content_for :title, title %>
<% if current_page?(controller: 'lettings_logs', action: 'index') %> <% if current_page?(controller: 'lettings_logs', action: 'index') %>
<% if @unresolved_count > 0 %>
<%= govuk_notification_banner(
title_text: "Important",
title_heading_level: 3,
title_id: "impacted-logs-banner",
) do |notification_banner| %>
<% notification_banner.heading(text: "A scheme has changed and it has affected #{@unresolved_count} #{'log'.pluralize(@unresolved_count)}") %>
<div class="govuk-notification-banner__heading">
<%= govuk_link_to "Update logs", update_logs_lettings_logs_path, class: "govuk-notification-banner__link" %>
</div>
<% end %>
<% end %>
<%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Lettings logs", sub: nil } : { main: "Lettings logs", sub: current_user.organisation.name } %> <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Lettings logs", sub: nil } : { main: "Lettings logs", sub: current_user.organisation.name } %>
<% elsif current_page?(controller: 'sales_logs', action: 'index') %> <% elsif current_page?(controller: 'sales_logs', action: 'index') %>
<%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Sales logs", sub: nil } : { main: "Sales logs", sub: current_user.organisation.name } %> <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Sales logs", sub: nil } : { main: "Sales logs", sub: current_user.organisation.name } %>

46
app/views/logs/update_logs.html.erb

@ -0,0 +1,46 @@
<% item_label = format_label(@pagy.count, "logs") %>
<% title = "Update logs" %>
<% content_for :title, title %>
<% if @total_count < 1 %>
<%= render partial: "organisations/headings", locals: { main: "There are no more logs that need updating", sub: "" } %>
<p class="govuk-body">
You’ve completed all the logs that were affected by scheme changes.
</p>
<div>
<%= govuk_button_link_to "Back to all logs", lettings_logs_path %>
</div>
<% else %>
<%= render partial: "organisations/headings", locals: { main: "You need to update #{@total_count} logs", sub: "" } %>
<%= govuk_table do |table| %>
<% table.head do |head| %>
<% head.row do |row| %>
<% row.cell(header: true, text: "Log ID") %>
<% row.cell(header: true, text: "Tenancy code") %>
<% row.cell(header: true, text: "Property reference") %>
<% row.cell(header: true, text: "Status") %>
<% row.cell(header: true, text: "") %>
<% end %>
<% end %>
<% @logs.each do |log| %>
<% table.body do |body| %>
<% body.row do |row| %>
<% row.cell(text: log.id) %>
<% row.cell(text: log.tenancycode) %>
<% row.cell(text: log.propcode) %>
<% row.cell(text: status_tag(log.status)) %>
<% row.cell(html_attributes: {
scope: "row",
class: "govuk-!-text-align-right",
}) do %>
<%= govuk_link_to("Update now", send(log.form.unresolved_log_path, log)) %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<% end %>
<%= render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>

1
config/forms/2021_2022.json

@ -2,6 +2,7 @@
"form_type": "lettings", "form_type": "lettings",
"start_date": "2021-04-01T00:00:00.000+01:00", "start_date": "2021-04-01T00:00:00.000+01:00",
"end_date": "2022-09-05T00:00:00.000+01:00", "end_date": "2022-09-05T00:00:00.000+01:00",
"unresolved_log_redirect_page_id": "tenancy_start_date",
"sections": { "sections": {
"tenancy_and_property": { "tenancy_and_property": {
"label": "Property and tenancy information", "label": "Property and tenancy information",

1
config/forms/2022_2023.json

@ -2,6 +2,7 @@
"form_type": "lettings", "form_type": "lettings",
"start_date": "2022-04-01T00:00:00.000+01:00", "start_date": "2022-04-01T00:00:00.000+01:00",
"end_date": "2023-07-01T00:00:00.000+01:00", "end_date": "2023-07-01T00:00:00.000+01:00",
"unresolved_log_redirect_page_id": "tenancy_start_date",
"sections": { "sections": {
"tenancy_and_property": { "tenancy_and_property": {
"label": "Property and tenancy information", "label": "Property and tenancy information",

1
config/routes.rb

@ -117,6 +117,7 @@ Rails.application.routes.draw do
get :start get :start
end end
end end
get "update-logs", to: "lettings_logs#update_logs"
end end
member do member do

7
db/migrate/20221125102013_add_impacted_by_deactivation_column.rb

@ -0,0 +1,7 @@
class AddImpactedByDeactivationColumn < ActiveRecord::Migration[7.0]
def change
change_table :lettings_logs, bulk: true do |t|
t.column :unresolved, :boolean
end
end
end

1
db/schema.rb

@ -237,6 +237,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_25_142847) do
t.integer "void_date_value_check" t.integer "void_date_value_check"
t.integer "housingneeds_type" t.integer "housingneeds_type"
t.integer "housingneeds_other" t.integer "housingneeds_other"
t.boolean "unresolved"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id" t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
t.index ["location_id"], name: "index_lettings_logs_on_location_id" t.index ["location_id"], name: "index_lettings_logs_on_location_id"
t.index ["managing_organisation_id"], name: "index_lettings_logs_on_managing_organisation_id" t.index ["managing_organisation_id"], name: "index_lettings_logs_on_managing_organisation_id"

4
spec/fixtures/files/lettings_logs_download.csv vendored

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

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

1
spec/fixtures/forms/2021_2022.json vendored

@ -2,6 +2,7 @@
"form_type": "lettings", "form_type": "lettings",
"start_date": "2021-04-01T00:00:00.000+01:00", "start_date": "2021-04-01T00:00:00.000+01:00",
"end_date": "2022-07-01T00:00:00.000+01:00", "end_date": "2022-07-01T00:00:00.000+01:00",
"unresolved_log_redirect_page_id": "tenancy_start_date",
"sections": { "sections": {
"household": { "household": {
"label": "About the household", "label": "About the household",

1
spec/fixtures/forms/2022_2023.json vendored

@ -2,6 +2,7 @@
"form_type": "lettings", "form_type": "lettings",
"start_date": "2022-04-01T00:00:00.000+01:00", "start_date": "2022-04-01T00:00:00.000+01:00",
"end_date": "2023-07-01T00:00:00.000+01:00", "end_date": "2023-07-01T00:00:00.000+01:00",
"unresolved_log_redirect_page_id": "tenancy_start_date",
"sections": { "sections": {
"household": { "household": {
"label": "About the household", "label": "About the household",

10
spec/models/form_spec.rb

@ -224,6 +224,7 @@ RSpec.describe Form, type: :model do
expect(form.questions.first.id).to eq("owning_organisation_id") expect(form.questions.first.id).to eq("owning_organisation_id")
expect(form.start_date).to eq(Time.zone.parse("2022-04-01")) expect(form.start_date).to eq(Time.zone.parse("2022-04-01"))
expect(form.end_date).to eq(Time.zone.parse("2023-07-01")) expect(form.end_date).to eq(Time.zone.parse("2023-07-01"))
expect(form.unresolved_log_redirect_page_id).to eq(nil)
end end
it "can correctly define sections in the sales form" do it "can correctly define sections in the sales form" do
@ -269,4 +270,13 @@ RSpec.describe Form, type: :model do
end end
end end
end end
describe "when creating a lettings log", :aggregate_failures do
it "creates a valid lettings form" do
form = described_class.new("spec/fixtures/forms/2021_2022.json")
expect(form.type).to eq("lettings")
expect(form.name).to eq("2021_2022_lettings")
expect(form.unresolved_log_redirect_page_id).to eq("tenancy_start_date")
end
end
end end

110
spec/requests/lettings_logs_controller_spec.rb

@ -706,6 +706,29 @@ RSpec.describe LettingsLogsController, type: :request do
expect(response).to have_http_status(:not_found) expect(response).to have_http_status(:not_found)
end end
end end
context "when the log is unresolved" do
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) }
let!(:location) { FactoryBot.create(:location, scheme:) }
before do
FactoryBot.create_list(:lettings_log, 3, unresolved: true, created_by: user)
lettings_log.update!(needstype: 2, scheme:, location:, unresolved: true)
sign_in user
get "/lettings-logs/#{lettings_log.id}", headers:, params: {}
end
it "marks it as resolved when both scheme and location exist" do
lettings_log.reload
expect(lettings_log.unresolved).to eq(false)
end
it "displays a success banner" do
expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success")
expect(page).to have_content("You’ve updated all the fields affected by the scheme change")
expect(page).to have_link("Update 3 more logs", href: "/lettings-logs/update-logs")
end
end
end end
end end
end end
@ -789,6 +812,93 @@ RSpec.describe LettingsLogsController, type: :request do
end end
end end
end end
context "when viewing a collection of logs affected by deactivated location" do
let!(:affected_lettings_logs) { FactoryBot.create_list(:lettings_log, 3, unresolved: true, created_by: user) }
let!(:non_affected_lettings_logs) { FactoryBot.create_list(:lettings_log, 4, created_by: user) }
let(:other_user) { FactoryBot.create(:user, organisation: user.organisation) }
let(:headers) { { "Accept" => "text/html" } }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
end
it "displays logs in a table" do
get "/lettings-logs/update-logs", headers:, params: {}
expect(page).to have_content("Log ID")
expect(page).to have_content("Tenancy code")
expect(page).to have_content("Property reference")
expect(page).to have_content("Status")
expect(page).to have_content(affected_lettings_logs.first.id)
expect(page).to have_content(affected_lettings_logs.first.tenancycode)
expect(page).to have_content(affected_lettings_logs.first.propcode)
expect(page).to have_link("Update now", href: "/lettings-logs/#{affected_lettings_logs.first.id}/tenancy-start-date")
end
it "only displays affected logs" do
get "/lettings-logs/update-logs", headers:, params: {}
expect(page).to have_content("You need to update 3 logs")
expect(page).to have_content(affected_lettings_logs.first.id)
expect(page).not_to have_content(non_affected_lettings_logs.first.id)
end
it "only displays the logs creted by the user" do
affected_lettings_logs.first.update!(created_by: other_user)
get "/lettings-logs/update-logs", headers:, params: {}
expect(page).to have_content(affected_lettings_logs.second.id)
expect(page).not_to have_content(affected_lettings_logs.first.id)
expect(page).to have_content("You need to update 2 logs")
end
it "displays correct content when there are no unresolved logs" do
LettingsLog.where(unresolved: true).update!(unresolved: false)
get "/lettings-logs/update-logs", headers:, params: {}
expect(page).to have_content("There are no more logs that need updating")
expect(page).to have_content("You’ve completed all the logs that were affected by scheme changes.")
page.assert_selector(".govuk-button", text: "Back to all logs")
end
it "displays a banner on the lettings log page" do
get "/lettings-logs", headers:, params: {}
expect(page).to have_css(".govuk-notification-banner")
expect(page).to have_content("A scheme has changed and it has affected 3 logs")
expect(page).to have_link("Update logs", href: "/lettings-logs/update-logs")
end
end
context "when viewing a specific log affected by deactivated location" do
let!(:affected_lettings_log) { FactoryBot.create(:lettings_log, unresolved: true, created_by: user, needstype: 2) }
let(:headers) { { "Accept" => "text/html" } }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
end
it "routes to the tenancy date question" do
get "/lettings-logs/#{affected_lettings_log.id}", headers:, params: {}
expect(response).to redirect_to("/lettings-logs/#{affected_lettings_log.id}/tenancy-start-date")
follow_redirect!
expect(page).to have_content("What is the tenancy start date?")
end
it "tenancy start date page links to the scheme page" do
get "/lettings-logs/#{affected_lettings_log.id}/tenancy-start-date", headers:, params: {}
expect(page).to have_link("Skip for now", href: "/lettings-logs/#{affected_lettings_log.id}/scheme")
end
it "scheme page links to the locations page" do
get "/lettings-logs/#{affected_lettings_log.id}/scheme", headers:, params: {}
expect(page).to have_link("Skip for now", href: "/lettings-logs/#{affected_lettings_log.id}/location")
end
it "displays inset hint text on the tenancy start date question" do
get "/lettings-logs/#{affected_lettings_log.id}/tenancy-start-date", headers:, params: {}
expect(page).to have_content("Some scheme details have changed, and now this log needs updating. Check that the tenancy start date is correct.")
end
end
end end
describe "PATCH" do describe "PATCH" do

12
spec/requests/locations_controller_spec.rb

@ -1364,6 +1364,12 @@ RSpec.describe LocationsController, type: :request do
expect(lettings_log.location).to eq(nil) expect(lettings_log.location).to eq(nil)
expect(lettings_log.scheme).to eq(nil) expect(lettings_log.scheme).to eq(nil)
end end
it "marks log as needing attention" do
expect(lettings_log.unresolved).to eq(nil)
lettings_log.reload
expect(lettings_log.unresolved).to eq(true)
end
end end
context "and a log startdate is before location deactivation date" do context "and a log startdate is before location deactivation date" do
@ -1376,6 +1382,12 @@ RSpec.describe LocationsController, type: :request do
expect(lettings_log.location).to eq(location) expect(lettings_log.location).to eq(location)
expect(lettings_log.scheme).to eq(scheme) expect(lettings_log.scheme).to eq(scheme)
end end
it "does not mark log as needing attention" do
expect(lettings_log.unresolved).to eq(nil)
lettings_log.reload
expect(lettings_log.unresolved).to eq(nil)
end
end end
end end

12
spec/requests/schemes_controller_spec.rb

@ -1870,6 +1870,12 @@ RSpec.describe SchemesController, type: :request do
expect(lettings_log.scheme).to eq(nil) expect(lettings_log.scheme).to eq(nil)
expect(lettings_log.scheme).to eq(nil) expect(lettings_log.scheme).to eq(nil)
end end
it "marks log as needing attention" do
expect(lettings_log.unresolved).to eq(nil)
lettings_log.reload
expect(lettings_log.unresolved).to eq(true)
end
end end
context "and a log startdate is before scheme deactivation date" do context "and a log startdate is before scheme deactivation date" do
@ -1882,6 +1888,12 @@ RSpec.describe SchemesController, type: :request do
expect(lettings_log.scheme).to eq(scheme) expect(lettings_log.scheme).to eq(scheme)
expect(lettings_log.scheme).to eq(scheme) expect(lettings_log.scheme).to eq(scheme)
end end
it "does not mark log as needing attention" do
expect(lettings_log.unresolved).to eq(nil)
lettings_log.reload
expect(lettings_log.unresolved).to eq(nil)
end
end end
end end

1
spec/services/csv/lettings_log_csv_service_spec.rb

@ -200,6 +200,7 @@ RSpec.describe Csv::LettingsLogCsvService do
hhtype hhtype
new_old new_old
vacdays vacdays
unresolved
unittype_sh unittype_sh
scheme_code scheme_code
scheme_service_name scheme_service_name

Loading…
Cancel
Save