diff --git a/app/controllers/lettings_logs_controller.rb b/app/controllers/lettings_logs_controller.rb index eaec5a604..40560fca8 100644 --- a/app/controllers/lettings_logs_controller.rb +++ b/app/controllers/lettings_logs_controller.rb @@ -13,6 +13,7 @@ class LettingsLogsController < LogsController @pagy, @logs = pagy(unpaginated_filtered_logs) @searched = search_term.presence @total_count = all_logs.size + @unresolved_count = all_logs.unresolved.created_by(current_user).count render "logs/index" end end @@ -37,6 +38,7 @@ class LettingsLogsController < LogsController def show respond_to do |format| # We don't have a dedicated non-editable show view + resolve_logs! format.html { edit } format.json do if @log @@ -51,7 +53,11 @@ class LettingsLogsController < LogsController def edit @log = current_user.lettings_logs.find_by(id: params[:id]) 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 render_not_found end @@ -83,6 +89,18 @@ class LettingsLogsController < LogsController 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 def permitted_log_params @@ -96,4 +114,11 @@ private def post_create_redirect_url(log) lettings_log_url(log) 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 diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 1da3bf5c4..bf812e990 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -219,7 +219,7 @@ private end 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 def toggle_date(key) diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index 389446b7f..153a81924 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -349,6 +349,6 @@ private end 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 diff --git a/app/helpers/unresolved_log_helper.rb b/app/helpers/unresolved_log_helper.rb new file mode 100644 index 000000000..f9ad59124 --- /dev/null +++ b/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.
" + notice_message << " Update #{count} more #{'log'.pluralize(count)}" if count.positive? + notice_message + end +end diff --git a/app/models/form.rb b/app/models/form.rb index 9d9acf2ea..022b9c261 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -1,7 +1,7 @@ class Form attr_reader :form_definition, :sections, :subsections, :pages, :questions, :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") if type == "sales" @@ -33,6 +33,7 @@ class Form @questions = pages.flat_map(&:questions) @start_date = Time.iso8601(form_definition["start_date"]) @end_date = Time.iso8601(form_definition["end_date"]) + @unresolved_log_redirect_page_id = form_definition["unresolved_log_redirect_page_id"] end @name = "#{start_date.year}_#{end_date.year}_#{type}" end @@ -56,6 +57,8 @@ class Form end 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_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) @@ -84,6 +87,10 @@ class Form "#{log.class.name.underscore}_#{page.subsection.id}_check_answers_path" end + def unresolved_log_path + "#{type}_log_#{unresolved_log_redirect_page_id}_path" + end + def next_incomplete_section_redirect_path(subsection, log) subsection_ids = subsections.map(&:id) diff --git a/app/models/form/lettings/pages/location.rb b/app/models/form/lettings/pages/location.rb index 982f4c109..d15091cb5 100644 --- a/app/models/form/lettings/pages/location.rb +++ b/app/models/form/lettings/pages/location.rb @@ -7,6 +7,7 @@ class Form::Lettings::Pages::Location < ::Form::Page "needstype" => 2, "scheme_has_multiple_locations?" => true, }] + @next_unresolved_page_id = :check_answers end def questions diff --git a/app/models/form/lettings/pages/scheme.rb b/app/models/form/lettings/pages/scheme.rb index c17eaab04..77828e1cf 100644 --- a/app/models/form/lettings/pages/scheme.rb +++ b/app/models/form/lettings/pages/scheme.rb @@ -6,6 +6,7 @@ class Form::Lettings::Pages::Scheme < ::Form::Page @depends_on = [{ "needstype" => 2, }] + @next_unresolved_page_id = "location" end def questions diff --git a/app/models/form/lettings/pages/tenancy_start_date.rb b/app/models/form/lettings/pages/tenancy_start_date.rb index 562153dc2..fd0810893 100644 --- a/app/models/form/lettings/pages/tenancy_start_date.rb +++ b/app/models/form/lettings/pages/tenancy_start_date.rb @@ -4,6 +4,7 @@ class Form::Lettings::Pages::TenancyStartDate < ::Form::Page @id = "tenancy_start_date" @description = "" @subsection = subsection + @next_unresolved_page_id = "scheme" end def questions diff --git a/app/models/form/lettings/questions/tenancy_start_date.rb b/app/models/form/lettings/questions/tenancy_start_date.rb index f7e2622ac..925eb00bc 100644 --- a/app/models/form/lettings/questions/tenancy_start_date.rb +++ b/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" @header = "What is the tenancy start 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 end end diff --git a/app/models/form/page.rb b/app/models/form/page.rb index 5bf1e1618..33e944eed 100644 --- a/app/models/form/page.rb +++ b/app/models/form/page.rb @@ -1,6 +1,6 @@ class Form::Page 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) @id = id @@ -14,6 +14,7 @@ class Form::Page @title_text = hsh["title_text"] @informative_text = hsh["informative_text"] @hide_subsection_label = hsh["hide_subsection_label"] + @next_unresolved_page_id = hsh["next_unresolved_page_id"] end end diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 13b1c62c9..05e712e38 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -3,7 +3,8 @@ class Form::Question :type, :min, :max, :step, :width, :fields_to_add, :result_field, :conditional_for, :readonly, :answer_options, :page, :check_answer_label, :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 TOP = 1 @@ -38,6 +39,7 @@ class Form::Question @requires_js = hsh["requires_js"] @fields_added = hsh["fields_added"] @check_answers_card_number = hsh["check_answers_card_number"] || 0 + @unresolved_hint_text = hsh["unresolved_hint_text"] end end diff --git a/app/models/lettings_log.rb b/app/models/lettings_log.rb index fb17bb613..610ddbd75 100644 --- a/app/models/lettings_log.rb +++ b/app/models/lettings_log.rb @@ -46,6 +46,7 @@ class LettingsLog < Log .or(filter_by_id(param)) } 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 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?) end + def resolve! + update(unresolved: false) + end + private PIO = PostcodeService.new diff --git a/app/models/log.rb b/app/models/log.rb index abde757e5..4ddb63246 100644 --- a/app/models/log.rb +++ b/app/models/log.rb @@ -23,6 +23,7 @@ class Log < ApplicationRecord where(created_by: user) end } + scope :created_by, ->(user) { where(created_by: user) } def collection_start_year return @start_year if @start_year diff --git a/app/models/sales_log.rb b/app/models/sales_log.rb index 703da2911..5a2e045bc 100644 --- a/app/models/sales_log.rb +++ b/app/models/sales_log.rb @@ -56,4 +56,8 @@ class SalesLog < Log def setup_completed? form.setup_sections.all? { |sections| sections.subsections.all? { |subsection| subsection.status(self) == :completed } } end + + def unresolved + false + end end diff --git a/app/services/csv/lettings_log_csv_service.rb b/app/services/csv/lettings_log_csv_service.rb index 66a98a20f..67078fb03 100644 --- a/app/services/csv/lettings_log_csv_service.rb +++ b/app/services/csv/lettings_log_csv_service.rb @@ -1,6 +1,6 @@ module Csv class LettingsLogCsvService - CSV_FIELDS_TO_OMIT = %w[hhmemb net_income_value_check first_time_property_let_as_social_housing renttype needstype postcode_known is_la_inferred totchild totelder totadult net_income_known is_carehome previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known letting_allocation_unknown details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge wtshortfall rent_value_check old_form_id old_id retirement_value_check tshortfall_known pregnancy_value_check hhtype new_old vacdays la prevloc].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) @user = user diff --git a/app/views/form/_date_question.html.erb b/app/views/form/_date_question.html.erb index 53abb5878..153679ace 100644 --- a/app/views/form/_date_question.html.erb +++ b/app/views/form/_date_question.html.erb @@ -5,6 +5,8 @@ legend: legend(question, page_header, conditional), hint: { text: question.hint_text&.html_safe || "For example, 1 9 2022." }, 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? %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index c52b587f3..16e403574 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -124,7 +124,7 @@ success: true, title_heading_level: 3, title_id: "swanky-notifications" ) do |notification_banner| - notification_banner.heading(text: flash.notice) + notification_banner.heading(text: flash.notice.html_safe) end %> <% end %> <%= content_for?(:content) ? yield(:content) : yield %> diff --git a/app/views/logs/index.html.erb b/app/views/logs/index.html.erb index a340973cf..3f0d2031d 100644 --- a/app/views/logs/index.html.erb +++ b/app/views/logs/index.html.erb @@ -4,6 +4,18 @@ <% content_for :title, title %> <% 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)}") %> +
+ <%= govuk_link_to "Update logs", update_logs_lettings_logs_path, class: "govuk-notification-banner__link" %> +
+ <% end %> + <% end %> <%= 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') %> <%= render partial: "organisations/headings", locals: current_user.support? ? { main: "Sales logs", sub: nil } : { main: "Sales logs", sub: current_user.organisation.name } %> diff --git a/app/views/logs/update_logs.html.erb b/app/views/logs/update_logs.html.erb new file mode 100644 index 000000000..1b744beb6 --- /dev/null +++ b/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: "" } %> +

+ You’ve completed all the logs that were affected by scheme changes. +

+
+ <%= govuk_button_link_to "Back to all logs", lettings_logs_path %> +
+<% 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" } %> diff --git a/config/forms/2021_2022.json b/config/forms/2021_2022.json index 19d8c291d..ca2fa6e2e 100644 --- a/config/forms/2021_2022.json +++ b/config/forms/2021_2022.json @@ -2,6 +2,7 @@ "form_type": "lettings", "start_date": "2021-04-01T00:00:00.000+01:00", "end_date": "2022-09-05T00:00:00.000+01:00", + "unresolved_log_redirect_page_id": "tenancy_start_date", "sections": { "tenancy_and_property": { "label": "Property and tenancy information", diff --git a/config/forms/2022_2023.json b/config/forms/2022_2023.json index fe1511153..51e1123ee 100644 --- a/config/forms/2022_2023.json +++ b/config/forms/2022_2023.json @@ -2,6 +2,7 @@ "form_type": "lettings", "start_date": "2022-04-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": { "tenancy_and_property": { "label": "Property and tenancy information", diff --git a/config/routes.rb b/config/routes.rb index aebc664ab..94a585821 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -117,6 +117,7 @@ Rails.application.routes.draw do get :start end end + get "update-logs", to: "lettings_logs#update_logs" end member do diff --git a/db/migrate/20221125102013_add_impacted_by_deactivation_column.rb b/db/migrate/20221125102013_add_impacted_by_deactivation_column.rb new file mode 100644 index 000000000..186b6cc06 --- /dev/null +++ b/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 diff --git a/db/schema.rb b/db/schema.rb index e5a4d27e4..4f40c8da5 100644 --- a/db/schema.rb +++ b/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 "housingneeds_type" t.integer "housingneeds_other" + t.boolean "unresolved" 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 ["managing_organisation_id"], name: "index_lettings_logs_on_managing_organisation_id" diff --git a/spec/fixtures/files/lettings_logs_download.csv b/spec/fixtures/files/lettings_logs_download.csv index 18c679926..26ee815d1 100644 --- a/spec/fixtures/files/lettings_logs_download.csv +++ b/spec/fixtures/files/lettings_logs_download.csv @@ -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},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,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} diff --git a/spec/fixtures/forms/2021_2022.json b/spec/fixtures/forms/2021_2022.json index 8e73f645b..7b169e80a 100644 --- a/spec/fixtures/forms/2021_2022.json +++ b/spec/fixtures/forms/2021_2022.json @@ -2,6 +2,7 @@ "form_type": "lettings", "start_date": "2021-04-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": { "household": { "label": "About the household", diff --git a/spec/fixtures/forms/2022_2023.json b/spec/fixtures/forms/2022_2023.json index 5f5671b6f..f618012f2 100644 --- a/spec/fixtures/forms/2022_2023.json +++ b/spec/fixtures/forms/2022_2023.json @@ -2,6 +2,7 @@ "form_type": "lettings", "start_date": "2022-04-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": { "household": { "label": "About the household", diff --git a/spec/models/form_spec.rb b/spec/models/form_spec.rb index f8bcddcca..a9a0c9b40 100644 --- a/spec/models/form_spec.rb +++ b/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.start_date).to eq(Time.zone.parse("2022-04-01")) expect(form.end_date).to eq(Time.zone.parse("2023-07-01")) + expect(form.unresolved_log_redirect_page_id).to eq(nil) end it "can correctly define sections in the sales form" do @@ -269,4 +270,13 @@ RSpec.describe Form, type: :model do 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 diff --git a/spec/requests/lettings_logs_controller_spec.rb b/spec/requests/lettings_logs_controller_spec.rb index db4226152..d41c4d0a5 100644 --- a/spec/requests/lettings_logs_controller_spec.rb +++ b/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) 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 @@ -789,6 +812,93 @@ RSpec.describe LettingsLogsController, type: :request do 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 describe "PATCH" do diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 45463ceb1..9fc1b0257 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/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.scheme).to eq(nil) 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 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.scheme).to eq(scheme) 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 diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index 0769e15c6..feef2f762 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/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) 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 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) 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 diff --git a/spec/services/csv/lettings_log_csv_service_spec.rb b/spec/services/csv/lettings_log_csv_service_spec.rb index bc5195d84..9b9c7ff87 100644 --- a/spec/services/csv/lettings_log_csv_service_spec.rb +++ b/spec/services/csv/lettings_log_csv_service_spec.rb @@ -200,6 +200,7 @@ RSpec.describe Csv::LettingsLogCsvService do hhtype new_old vacdays + unresolved unittype_sh scheme_code scheme_service_name