diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 532ab915a..6cd40161f 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -18,14 +18,36 @@ class LocationsController < ApplicationController @location = Location.new end + def show; end + + def deactivate + if params[:location].blank? + render "toggle_active", locals: { action: "deactivate" } + elsif params[:location][:confirm].present? && params[:location][:deactivation_date].present? + confirm_deactivation + else + deactivation_date_errors + if @location.errors.present? + @location.deactivation_date_type = params[:location][:deactivation_date_type] + render "toggle_active", locals: { action: "deactivate" }, status: :unprocessable_entity + else + render "toggle_active_confirm", locals: { action: "deactivate", deactivation_date: } + end + end + end + + def reactivate + render "toggle_active", locals: { action: "reactivate" } + end + def create if date_params_missing?(location_params) || valid_date_params?(location_params) @location = Location.new(location_params) if @location.save if @location.location_admin_district.nil? - redirect_to(location_edit_local_authority_path(id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) + redirect_to(scheme_location_edit_local_authority_path(scheme_id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) elsif location_params[:add_another_location] == "Yes" - redirect_to new_location_path(@scheme) + redirect_to new_scheme_location_path(@scheme) else check_answers_path = @scheme.confirmed? ? scheme_check_answers_path(@scheme, anchor: "locations") : scheme_check_answers_path(@scheme) redirect_to check_answers_path @@ -69,9 +91,9 @@ class LocationsController < ApplicationController case page when "edit" if @location.location_admin_district.nil? - redirect_to(location_edit_local_authority_path(id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) + redirect_to(scheme_location_edit_local_authority_path(scheme_id: @scheme.id, location_id: @location.id, add_another_location: location_params[:add_another_location])) elsif location_params[:add_another_location] == "Yes" - redirect_to(new_location_path(@location.scheme)) + redirect_to(new_scheme_location_path(@location.scheme)) else redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) end @@ -79,7 +101,7 @@ class LocationsController < ApplicationController redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) when "edit-local-authority" if params[:add_another_location] == "Yes" - redirect_to(new_location_path(@location.scheme)) + redirect_to(new_scheme_location_path(@location.scheme)) else redirect_to(scheme_check_answers_path(@scheme, anchor: "locations")) end @@ -107,7 +129,7 @@ private def find_scheme @scheme = if %w[new create index edit_name].include?(action_name) - Scheme.find(params[:id]) + Scheme.find(params[:scheme_id]) else @location&.scheme end @@ -122,7 +144,7 @@ private end def authenticate_action! - if %w[new edit update create index edit_name edit_local_authority].include?(action_name) && !((current_user.organisation == @scheme&.owning_organisation) || current_user.support?) + if %w[new edit update create index edit_name edit_local_authority deactivate].include?(action_name) && !((current_user.organisation == @scheme&.owning_organisation) || current_user.support?) render_not_found and return end end @@ -140,4 +162,49 @@ private def valid_location_admin_district?(location_params) location_params["location_admin_district"] != "Select an option" end + + def confirm_deactivation + if @location.update(deactivation_date: params[:location][:deactivation_date]) + flash[:notice] = "#{@location.name || @location.postcode} has been deactivated" + end + redirect_to scheme_location_path(@scheme, @location) + end + + def deactivation_date_errors + if params[:location][:deactivation_date].blank? && params[:location][:deactivation_date_type].blank? + @location.errors.add(:deactivation_date_type, message: I18n.t("validations.location.deactivation_date.not_selected")) + end + + if params[:location][:deactivation_date_type] == "other" + day = params[:location]["deactivation_date(3i)"] + month = params[:location]["deactivation_date(2i)"] + year = params[:location]["deactivation_date(1i)"] + + collection_start_date = FormHandler.instance.current_collection_start_date + + if [day, month, year].any?(&:blank?) + { day:, month:, year: }.each do |period, value| + @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.not_entered", period: period.to_s)) if value.blank? + end + elsif !Date.valid_date?(year.to_i, month.to_i, day.to_i) + @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.invalid")) + elsif !Date.new(year.to_i, month.to_i, day.to_i).between?(collection_start_date, Date.new(2200, 1, 1)) + @location.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation_date.out_of_range", date: collection_start_date.to_formatted_s(:govuk_date))) + end + end + end + + def deactivation_date + return if params[:location].blank? + + collection_start_date = FormHandler.instance.current_collection_start_date + return collection_start_date if params[:location][:deactivation_date_type] == "default" + return params[:location][:deactivation_date] if params[:location][:deactivation_date_type].blank? + + day = params[:location]["deactivation_date(3i)"] + month = params[:location]["deactivation_date(2i)"] + year = params[:location]["deactivation_date(1i)"] + + Date.new(year.to_i, month.to_i, day.to_i) + end end diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index c59a616a5..3470507a8 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -197,7 +197,7 @@ private when "secondary-client-group" scheme_support_path(@scheme) when "support" - new_location_path + new_scheme_location_path(@scheme) when "details" if @scheme.arrangement_type_before_type_cast == "D" scheme_primary_client_group_path(@scheme) diff --git a/app/helpers/check_answers_helper.rb b/app/helpers/check_answers_helper.rb index b334ab073..1583b3791 100644 --- a/app/helpers/check_answers_helper.rb +++ b/app/helpers/check_answers_helper.rb @@ -18,14 +18,14 @@ module CheckAnswersHelper def get_location_change_link_href_postcode(scheme, location) if location.confirmed? - location_edit_name_path(id: scheme.id, location_id: location.id) + scheme_location_edit_name_path(scheme_id: scheme.id, location_id: location.id) else - location_edit_path(id: scheme.id, location_id: location.id) + edit_scheme_location_path(scheme_id: scheme.id, id: location.id) end end def get_location_change_link_href_location_admin_district(scheme, location) - location_edit_local_authority_path(id: scheme.id, location_id: location.id) + scheme_location_edit_local_authority_path(scheme_id: scheme.id, location_id: location.id) end def any_questions_have_summary_card_number?(subsection, lettings_log) diff --git a/app/helpers/locations_helper.rb b/app/helpers/locations_helper.rb index e0fe9d18c..e21a4724e 100644 --- a/app/helpers/locations_helper.rb +++ b/app/helpers/locations_helper.rb @@ -22,4 +22,18 @@ module LocationsHelper resource.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } end + + def display_attributes(location) + [ + { name: "Postcode", value: location.postcode }, + { name: "Local authority", value: location.location_admin_district }, + { name: "Location name", value: location.name, edit: true }, + { name: "Total number of units at this location", value: location.units }, + { name: "Common type of unit", value: location.type_of_unit }, + { name: "Mobility type", value: location.mobility_type }, + { name: "Code", value: location.location_code }, + { name: "Availability", value: "Available from #{location.available_from.to_formatted_s(:govuk_date)}" }, + { name: "Status", value: location.status }, + ] + end end diff --git a/app/models/location.rb b/app/models/location.rb index 40a115d43..ab1c3620a 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -2,6 +2,7 @@ class Location < ApplicationRecord validate :validate_postcode validates :units, :type_of_unit, :mobility_type, presence: true belongs_to :scheme + has_many :lettings_logs, class_name: "LettingsLog" has_paper_trail @@ -9,7 +10,7 @@ class Location < ApplicationRecord auto_strip_attributes :name - attr_accessor :add_another_location + attr_accessor :add_another_location, :deactivation_date_type scope :search_by_postcode, ->(postcode) { where("REPLACE(postcode, ' ', '') ILIKE ?", "%#{postcode.delete(' ')}%") } scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } @@ -359,14 +360,6 @@ class Location < ApplicationRecord enum type_of_unit: TYPE_OF_UNIT - def display_attributes - [ - { name: "Location code ", value: location_code, suffix: false }, - { name: "Postcode", value: postcode, suffix: county }, - { name: "Type of unit", value: type_of_unit, suffix: false }, - ] - end - def postcode=(postcode) if postcode super UKPostcode.parse(postcode).to_s @@ -375,6 +368,16 @@ class Location < ApplicationRecord end end + def available_from + startdate || created_at + end + + def status + return :active if deactivation_date.blank? + return :deactivating_soon if Time.zone.now < deactivation_date + return :deactivated if Time.zone.now >= deactivation_date + end + private PIO = PostcodeService.new diff --git a/app/models/validations/financial_validations.rb b/app/models/validations/financial_validations.rb index 4dec7bb78..87c506b4d 100644 --- a/app/models/validations/financial_validations.rb +++ b/app/models/validations/financial_validations.rb @@ -34,10 +34,12 @@ module Validations::FinancialValidations if record.earnings.present? && record.incfreq.blank? record.errors.add :incfreq, I18n.t("validations.financial.earnings.freq_missing") + record.errors.add :earnings, I18n.t("validations.financial.earnings.freq_missing") end if record.incfreq.present? && record.earnings.blank? record.errors.add :earnings, I18n.t("validations.financial.earnings.earnings_missing") + record.errors.add :incfreq, I18n.t("validations.financial.earnings.earnings_missing") end end @@ -110,6 +112,7 @@ module Validations::FinancialValidations if record.is_carehome? period = record.form.get_question("period", record).label_from_value(record.period).downcase if record.chcharge.blank? + record.errors.add :is_carehome, I18n.t("validations.financial.carehome.not_provided", period:) record.errors.add :chcharge, I18n.t("validations.financial.carehome.not_provided", period:) elsif !weekly_value_in_range(record, "chcharge", 10, 1000) max_chcharge = record.weekly_to_value_per_period(1000) diff --git a/app/models/validations/property_validations.rb b/app/models/validations/property_validations.rb index d5ab8e9e0..c655d8c85 100644 --- a/app/models/validations/property_validations.rb +++ b/app/models/validations/property_validations.rb @@ -38,6 +38,10 @@ module Validations::PropertyValidations record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.referral_invalid") record.errors.add :referral, I18n.t("validations.household.referral.rsnvac_non_temp") end + + if record.renewal.present? && record.renewal.zero? && record.rsnvac == 14 + record.errors.add :rsnvac, I18n.t("validations.property.rsnvac.not_a_renewal") + end end def validate_unitletas(record) diff --git a/app/services/imports/import_service.rb b/app/services/imports/import_service.rb index e45498004..1db1f4d6a 100644 --- a/app/services/imports/import_service.rb +++ b/app/services/imports/import_service.rb @@ -19,8 +19,12 @@ module Imports end end - def field_value(xml_document, namespace, field) - xml_document.at_xpath("//#{namespace}:#{field}")&.text + def field_value(xml_document, namespace, field, *args) + xml_document.at_xpath("//#{namespace}:#{field}", *args)&.text + end + + def meta_field_value(xml_document, field) + field_value(xml_document, "meta", field, { "meta" => "http://data.gov.uk/core/metadata" }) end def overridden?(xml_document, namespace, field) diff --git a/app/services/imports/lettings_logs_field_import_service.rb b/app/services/imports/lettings_logs_field_import_service.rb index 218decb7a..e59e178f2 100644 --- a/app/services/imports/lettings_logs_field_import_service.rb +++ b/app/services/imports/lettings_logs_field_import_service.rb @@ -16,8 +16,8 @@ module Imports private def update_lettings_allocation(xml_doc) - old_id = field_value(xml_doc, "meta", "document-id") - previous_status = field_value(xml_doc, "meta", "status") + old_id = meta_field_value(xml_doc, "document-id") + previous_status = meta_field_value(xml_doc, "status") record = LettingsLog.find_by(old_id:) if record.present? && previous_status.include?("submitted") @@ -46,11 +46,11 @@ module Imports end def update_major_repairs(xml_doc) - old_id = field_value(xml_doc, "meta", "document-id") + old_id = meta_field_value(xml_doc, "document-id") record = LettingsLog.find_by(old_id:) if record.present? - previous_status = field_value(xml_doc, "meta", "status") + previous_status = meta_field_value(xml_doc, "status") major_repairs_date = compose_date(xml_doc, "MRCDAY", "MRCMONTH", "MRCYEAR") major_repairs = if major_repairs_date.present? && previous_status.include?("submitted") 1 @@ -69,7 +69,7 @@ module Imports end def update_tenant_code(xml_doc) - old_id = field_value(xml_doc, "meta", "document-id") + old_id = meta_field_value(xml_doc, "document-id") record = LettingsLog.find_by(old_id:) if record.present? diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb index c7721b666..ab15e7f3d 100644 --- a/app/services/imports/lettings_logs_import_service.rb +++ b/app/services/imports/lettings_logs_import_service.rb @@ -57,7 +57,7 @@ module Imports def create_log(xml_doc) attributes = {} - previous_status = field_value(xml_doc, "meta", "status") + previous_status = meta_field_value(xml_doc, "status") # Required fields for status complete or logic to work # Note: order matters when we derive from previous values (attributes parameter) @@ -191,9 +191,9 @@ module Imports # Not specific to our form but required for consistency (present in import) attributes["old_form_id"] = safe_string_as_integer(xml_doc, "FORM") - attributes["created_at"] = Time.zone.parse(field_value(xml_doc, "meta", "created-date")) - attributes["updated_at"] = Time.zone.parse(field_value(xml_doc, "meta", "modified-date")) - attributes["old_id"] = field_value(xml_doc, "meta", "document-id") + attributes["created_at"] = Time.zone.parse(meta_field_value(xml_doc, "created-date")) + attributes["updated_at"] = Time.zone.parse(meta_field_value(xml_doc, "modified-date")) + attributes["old_id"] = meta_field_value(xml_doc, "document-id") # Required for our form invalidated questions (not present in import) attributes["previous_la_known"] = attributes["prevloc"].nil? ? 0 : 1 @@ -205,8 +205,8 @@ module Imports # Supported Housing fields if attributes["needstype"] == GN_SH[:supported_housing] - location_old_visible_id = safe_string_as_integer(xml_doc, "_1cschemecode") - scheme_old_visible_id = safe_string_as_integer(xml_doc, "_1cmangroupcode") + location_old_visible_id = string_or_nil(xml_doc, "_1cschemecode") + scheme_old_visible_id = string_or_nil(xml_doc, "_1cmangroupcode") schemes = Scheme.where(old_visible_id: scheme_old_visible_id, owning_organisation_id: attributes["owning_organisation_id"]) location = Location.find_by(old_visible_id: location_old_visible_id, scheme: schemes) @@ -236,7 +236,7 @@ module Imports attributes["net_income_value_check"] = 0 # Sets the log creator - owner_id = field_value(xml_doc, "meta", "owner-user-id").strip + owner_id = meta_field_value(xml_doc, "owner-user-id").strip if owner_id.present? user = LegacyUser.find_by(old_user_id: owner_id)&.user @logger.warn "Missing user! We expected to find a legacy user with old_user_id #{owner_id}" unless user @@ -355,7 +355,7 @@ module Imports end def get_form_name_component(xml_doc, index) - form_name = field_value(xml_doc, "meta", "form-name") + form_name = meta_field_value(xml_doc, "form-name") form_type_components = form_name.split("-") form_type_components[index] end @@ -399,7 +399,7 @@ module Imports end def find_organisation_id(xml_doc, id_field) - old_visible_id = unsafe_string_as_integer(xml_doc, id_field) + old_visible_id = string_or_nil(xml_doc, id_field) organisation = Organisation.find_by(old_visible_id:) raise "Organisation not found with legacy ID #{old_visible_id}" if organisation.nil? diff --git a/app/services/imports/scheme_location_import_service.rb b/app/services/imports/scheme_location_import_service.rb index cdcd9448d..837be0b49 100644 --- a/app/services/imports/scheme_location_import_service.rb +++ b/app/services/imports/scheme_location_import_service.rb @@ -91,31 +91,25 @@ module Imports attributes["units"] = safe_string_as_integer(xml_doc, "total-units") attributes["type_of_unit"] = safe_string_as_integer(xml_doc, "unit-type") attributes["location_old_id"] = string_or_nil(xml_doc, "id") - attributes["location_old_visible_id"] = safe_string_as_integer(xml_doc, "visible-id") + attributes["location_old_visible_id"] = string_or_nil(xml_doc, "visible-id") attributes["scheme_old_id"] = string_or_nil(xml_doc, "mgmtgroup") attributes end def add_location(scheme, attributes) - if attributes["end_date"].nil? || attributes["end_date"] >= Time.zone.now - begin - Location.create!( - name: attributes["location_name"], - postcode: attributes["postcode"], - mobility_type: attributes["mobility_type"], - units: attributes["units"], - type_of_unit: attributes["type_of_unit"], - old_visible_id: attributes["location_old_visible_id"], - old_id: attributes["location_old_id"], - startdate: attributes["start_date"], - scheme:, - ) - rescue ActiveRecord::RecordNotUnique - @logger.warn("Location is already present with legacy ID #{attributes['location_old_id']}, skipping") - end - else - @logger.warn("Location with legacy ID #{attributes['location_old_id']} is expired (#{attributes['end_date']}), skipping") - end + Location.create!( + name: attributes["location_name"], + postcode: attributes["postcode"], + mobility_type: attributes["mobility_type"], + units: attributes["units"], + type_of_unit: attributes["type_of_unit"], + old_visible_id: attributes["location_old_visible_id"], + old_id: attributes["location_old_id"], + startdate: attributes["start_date"], + scheme:, + ) + rescue ActiveRecord::RecordNotUnique + @logger.warn("Location is already present with legacy ID #{attributes['location_old_id']}, skipping") end def find_scheme_to_merge(attributes) diff --git a/app/views/locations/edit.html.erb b/app/views/locations/edit.html.erb index 6e14503ed..dca0d04fb 100644 --- a/app/views/locations/edit.html.erb +++ b/app/views/locations/edit.html.erb @@ -7,7 +7,7 @@ ) %> <% end %> -<%= form_for(@location, method: :patch, url: location_path(@location)) do |f| %> +<%= form_for(@location, method: :patch, url: scheme_location_path(scheme_id: @scheme.id, id: @location.id)) do |f| %>
<%= f.govuk_error_summary %> diff --git a/app/views/locations/edit_local_authority.html.erb b/app/views/locations/edit_local_authority.html.erb index 43c351d28..1e5ab9fbb 100644 --- a/app/views/locations/edit_local_authority.html.erb +++ b/app/views/locations/edit_local_authority.html.erb @@ -5,7 +5,7 @@ ) %> <% end %> -<%= form_for(@location, method: :patch, url: location_path(location_id: @location.id, add_another_location: params[:add_another_location])) do |f| %> +<%= form_for(@location, method: :patch, url: scheme_location_path(scheme_id: @scheme.id, id: @location.id, add_another_location: params[:add_another_location])) do |f| %>
<%= f.govuk_error_summary %> diff --git a/app/views/locations/edit_name.html.erb b/app/views/locations/edit_name.html.erb index 087ca0812..7e75edf9d 100644 --- a/app/views/locations/edit_name.html.erb +++ b/app/views/locations/edit_name.html.erb @@ -3,11 +3,11 @@ <% content_for :before_content do %> <%= govuk_back_link( text: "Back", - href: "/schemes/#{@scheme.id}/locations", + href: scheme_location_path(@scheme, @location), ) %> <% end %> -<%= form_for(@location, method: :patch, url: location_path(location_id: @location.id)) do |f| %> +<%= form_for(@location, method: :patch, url: scheme_location_path(scheme_id: @scheme.id, id: @location.id)) do |f| %>
<%= f.govuk_error_summary %> diff --git a/app/views/locations/index.html.erb b/app/views/locations/index.html.erb index 6672fc661..5b2cbae47 100644 --- a/app/views/locations/index.html.erb +++ b/app/views/locations/index.html.erb @@ -52,7 +52,7 @@ <%= table.body do |body| %> <%= body.row do |row| %> <% row.cell(text: location.id) %> - <% row.cell(text: simple_format(location_cell_postcode(location, "/schemes/#{@scheme.id}/locations/#{location.id}/edit-name"), { class: "govuk-!-font-weight-bold" }, wrapper_tag: "div")) %> + <% row.cell(text: simple_format(location_cell_postcode(location, "/schemes/#{@scheme.id}/locations/#{location.id}"), { class: "govuk-!-font-weight-bold" }, wrapper_tag: "div")) %> <% row.cell(text: location.units) %> <% row.cell(text: simple_format("#{location.type_of_unit}")) %> <% row.cell(text: location.mobility_type) %> @@ -62,6 +62,6 @@ <% end %> <% end %> <% end %> -<%= govuk_button_link_to "Add a location", new_location_path(id: @scheme.id), secondary: true %> +<%= govuk_button_link_to "Add a location", new_scheme_location_path(scheme_id: @scheme.id), secondary: true %> <%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "locations" } %> diff --git a/app/views/locations/new.html.erb b/app/views/locations/new.html.erb index 71690f8e6..69f56744b 100644 --- a/app/views/locations/new.html.erb +++ b/app/views/locations/new.html.erb @@ -7,7 +7,7 @@ ) %> <% end %> -<%= form_for(@location, method: :post, url: locations_path) do |f| %> +<%= form_for(@location, method: :post, url: scheme_locations_path) do |f| %>
<%= f.govuk_error_summary %> diff --git a/app/views/locations/show.html.erb b/app/views/locations/show.html.erb new file mode 100644 index 000000000..ccc0163c2 --- /dev/null +++ b/app/views/locations/show.html.erb @@ -0,0 +1,32 @@ +<% title = @location.name %> +<% content_for :title, title %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: scheme_locations_path(@scheme), + ) %> +<% end %> + +<%= render partial: "organisations/headings", locals: { main: @location.postcode, sub: @location.name } %> + +
+
+ <%= govuk_summary_list do |summary_list| %> + <% display_attributes(@location).each do |attr| %> + <%= summary_list.row do |row| %> + <% row.key { attr[:name] } %> + <% row.value { attr[:name].eql?("Status") ? status_tag(attr[:value]) : details_html(attr) } %> + <% row.action(text: "Change", href: scheme_location_edit_name_path(scheme_id: @scheme.id, location_id: @location.id)) if attr[:edit] %> + <% end %> + <% end %> + <% end %> +
+
+<% if FeatureToggle.location_toggle_enabled? %> + <% if @location.status == :active %> + <%= govuk_button_link_to "Deactivate this location", scheme_location_deactivate_path(scheme_id: @scheme.id, location_id: @location.id), warning: true %> + <% else %> + <%= govuk_button_link_to "Reactivate this location", scheme_location_reactivate_path(scheme_id: @scheme.id, location_id: @location.id) %> + <% end %> +<% end %> diff --git a/app/views/locations/toggle_active.html.erb b/app/views/locations/toggle_active.html.erb new file mode 100644 index 000000000..96cda6daa --- /dev/null +++ b/app/views/locations/toggle_active.html.erb @@ -0,0 +1,39 @@ +<% title = "#{action.humanize} #{@location.postcode}" %> +<% content_for :title, title %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: scheme_location_path(scheme_id: @location.scheme.id, id: @location.id), + ) %> +<% end %> + +<%= form_with model: @location, url: scheme_location_deactivate_path(scheme_id: @location.scheme.id, location_id: @location.id), method: "patch", local: true do |f| %> +
+
+ <% collection_start_date = FormHandler.instance.current_collection_start_date %> + <%= f.govuk_error_summary %> + <%= f.govuk_radio_buttons_fieldset :deactivation_date_type, + legend: { text: I18n.t("questions.location.deactivation.apply_from") }, + caption: { text: "Deactivate #{@location.postcode}" }, + hint: { text: I18n.t("hints.location.deactivation", date: collection_start_date.to_formatted_s(:govuk_date)) } do %> + <%= govuk_warning_text text: I18n.t("warnings.location.deactivation.existing_logs") %> + <%= f.govuk_radio_button :deactivation_date_type, + "default", + label: { text: "From the start of the current collection period (#{collection_start_date.to_formatted_s(:govuk_date)})" } %> + + <%= f.govuk_radio_button :deactivation_date_type, + "other", + label: { text: "For tenancies starting after a certain date" }, + **basic_conditional_html_attributes({ "deactivation_date" => %w[other] }, "location") do %> + <%= f.govuk_date_field :deactivation_date, + legend: { text: "Date", size: "m" }, + hint: { text: "For example, 27 3 2008" }, + width: 20 %> + <% end %> + <% end %> + + <%= f.govuk_submit "Continue" %> +
+
+<% end %> diff --git a/app/views/locations/toggle_active_confirm.html.erb b/app/views/locations/toggle_active_confirm.html.erb new file mode 100644 index 000000000..452d66e48 --- /dev/null +++ b/app/views/locations/toggle_active_confirm.html.erb @@ -0,0 +1,16 @@ +<%= form_with model: @location, url: scheme_location_deactivate_path(@location), method: "patch", local: true do |f| %> + <% content_for :before_content do %> + <%= govuk_back_link(href: :back) %> + <% end %> +

+ <%= @location.postcode %> + <%= "This change will affect #{@location.lettings_logs.count} logs" %> +

+ <%= govuk_warning_text text: I18n.t("warnings.location.deactivation.review_logs") %> + <%= f.hidden_field :confirm, value: true %> + <%= f.hidden_field :deactivation_date, value: deactivation_date %> +
+ <%= f.govuk_submit "Deactivate this location" %> + <%= govuk_button_link_to "Cancel", scheme_location_path(scheme_id: @scheme, id: @location.id), html: { method: :get }, secondary: true %> +
+ <% end %> diff --git a/app/views/schemes/check_answers.html.erb b/app/views/schemes/check_answers.html.erb index 2cb154e1f..a41b202ad 100644 --- a/app/views/schemes/check_answers.html.erb +++ b/app/views/schemes/check_answers.html.erb @@ -78,7 +78,7 @@ <% end %> <% end %> <% end %> - <%= govuk_button_link_to "Add a location", new_location_path(id: @scheme.id), secondary: true %> + <%= govuk_button_link_to "Add a location", new_scheme_location_path(scheme_id: @scheme.id), secondary: true %> <% end %> <% end %> <%= f.hidden_field :page, value: "check-answers" %> diff --git a/config/initializers/feature_toggle.rb b/config/initializers/feature_toggle.rb index b9315c577..982913b16 100644 --- a/config/initializers/feature_toggle.rb +++ b/config/initializers/feature_toggle.rb @@ -20,4 +20,10 @@ class FeatureToggle false end + + def self.location_toggle_enabled? + return true unless Rails.env.production? + + false + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 927cb91b1..8a2c45651 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -141,6 +141,7 @@ en: previous_let_social: "Property cannot have a previous let type if being let as social housing for the first time" non_temp_accommodation: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as this accommodation is not temporary" referral_invalid: "Answer cannot be re-let to tenant who occupied the same property as temporary accommodation as a different source of referral for this letting" + not_a_renewal: "Reason for vacancy cannot be 'Renewal of fixed-term tenancy' if letting is not a renewal" unittype_gn: one_bedroom_bedsit: "A bedsit can only have one bedroom" one_seven_bedroom_shared: "A shared house must have 1 to 7 bedrooms" @@ -318,6 +319,13 @@ en: invalid: "Enter a valid date" out_of_range: "The date must be on or after the %{date}" + location: + deactivation_date: + not_selected: "Select one of the options" + not_entered: "Enter a day, month and year" + invalid: "Enter a valid date" + out_of_range: "The date must be on or after the %{date}" + soft_validations: net_income: title_text: "Net income is outside the expected range based on the lead tenant’s working situation" @@ -368,6 +376,8 @@ en: startdate: "When did the first property in this location become available under this scheme? (optional)" add_another_location: "Do you want to add another location?" mobility_type: "What are the mobility standards for the majority of units in this location?" + deactivation: + apply_from: "When should this change apply?" scheme: deactivation: apply_from: "When should this change apply?" @@ -383,10 +393,15 @@ en: postcode: "For example, SW1P 4DF." name: "This is how you refer to this location within your organisation" units: "A unit can be a bedroom in a shared house or flat, or a house with 4 bedrooms. Do not include bedrooms used for wardens, managers, volunteers or sleep-in staff." + deactivation: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed." scheme: deactivation: "If the date is before %{date}, select ‘From the start of the current collection period’ because the previous period has now closed." warnings: + location: + deactivation: + existing_logs: "It will not be possible to add logs with this location if their tenancy start date is on or after the date you enter. Any existing logs may be affected." + review_logs: "Your data providers will need to review these logs and answer a few questions again. We’ll email each log creator with a list of logs that need updating." scheme: deactivation: existing_logs: "It will not be possible to add logs with this scheme if their tenancy start date is on or after the date you enter. Any existing logs may be affected." diff --git a/config/routes.rb b/config/routes.rb index d06a358eb..58890b4c0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,12 +54,12 @@ Rails.application.routes.draw do patch "deactivate", to: "schemes#deactivate" patch "reactivate", to: "schemes#reactivate" - member do - resources :locations do - get "edit-name", to: "locations#edit_name" - get "edit", to: "locations#edit" - get "edit-local-authority", to: "locations#edit_local_authority" - end + resources :locations do + get "edit-name", to: "locations#edit_name" + get "edit-local-authority", to: "locations#edit_local_authority" + get "deactivate", to: "locations#deactivate" + get "reactivate", to: "locations#reactivate" + patch "deactivate", to: "locations#deactivate" end end diff --git a/db/migrate/20221109122033_add_deactivation_date_to_locations.rb b/db/migrate/20221109122033_add_deactivation_date_to_locations.rb new file mode 100644 index 000000000..3360bfc7c --- /dev/null +++ b/db/migrate/20221109122033_add_deactivation_date_to_locations.rb @@ -0,0 +1,5 @@ +class AddDeactivationDateToLocations < ActiveRecord::Migration[7.0] + def change + add_column :locations, :deactivation_date, :datetime + end +end diff --git a/db/migrate/20221111102656_change_old_visible_id_type.rb b/db/migrate/20221111102656_change_old_visible_id_type.rb new file mode 100644 index 000000000..d4c568bb7 --- /dev/null +++ b/db/migrate/20221111102656_change_old_visible_id_type.rb @@ -0,0 +1,13 @@ +class ChangeOldVisibleIdType < ActiveRecord::Migration[7.0] + def up + change_column :organisations, :old_visible_id, :string + change_column :schemes, :old_visible_id, :string + change_column :locations, :old_visible_id, :string + end + + def down + change_column :organisations, :old_visible_id, :integer + change_column :schemes, :old_visible_id, :integer + change_column :locations, :old_visible_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 991a31264..1ff8f157c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2022_11_10_163351) do +ActiveRecord::Schema[7.0].define(version: 2022_11_11_102656) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -255,11 +255,12 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_10_163351) do t.integer "units" t.integer "type_of_unit" t.string "old_id" - t.integer "old_visible_id" + t.string "old_visible_id" t.string "mobility_type" t.datetime "startdate", precision: nil t.string "location_admin_district" t.boolean "confirmed" + t.datetime "deactivation_date" t.index ["old_id"], name: "index_locations_on_old_id", unique: true t.index ["scheme_id"], name: "index_locations_on_scheme_id" end @@ -315,7 +316,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_10_163351) do t.integer "supported_housing_units" t.integer "unspecified_units" t.string "old_org_id" - t.integer "old_visible_id" + t.string "old_visible_id" t.index ["old_visible_id"], name: "index_organisations_on_old_visible_id", unique: true end @@ -394,7 +395,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_11_10_163351) do t.bigint "managing_organisation_id" t.string "arrangement_type" t.string "old_id" - t.integer "old_visible_id" + t.string "old_visible_id" t.integer "total_units" t.boolean "confirmed" t.datetime "deactivation_date" diff --git a/spec/factories/location.rb b/spec/factories/location.rb index a8418f8ba..3359f64cd 100644 --- a/spec/factories/location.rb +++ b/spec/factories/location.rb @@ -17,7 +17,7 @@ FactoryBot.define do units { 20 } mobility_type { "A" } scheme { FactoryBot.create(:scheme, :export) } - old_visible_id { 111 } + old_visible_id { "111" } end end end diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index 35a380fb5..48f386fa7 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -692,7 +692,7 @@ RSpec.describe "Schemes scheme Features" do context "when I click to see individual scheme" do let(:scheme) { schemes.first } - let!(:location) { FactoryBot.create(:location, scheme:) } + let!(:location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 4), scheme:) } before do click_link(scheme.service_name) @@ -757,11 +757,31 @@ RSpec.describe "Schemes scheme Features" do click_link(location.postcode) end - it "shows available fields to edit" do - expect(page).to have_current_path("/schemes/#{scheme.id}/locations/#{location.id}/edit-name") + it "displays details about the selected location" do + expect(page).to have_current_path("/schemes/#{scheme.id}/locations/#{location.id}") + expect(page).to have_content(location.postcode) + expect(page).to have_content(location.location_admin_district) + expect(page).to have_content(location.name) + expect(page).to have_content(location.units) + expect(page).to have_content(location.type_of_unit) + expect(page).to have_content(location.mobility_type) + expect(page).to have_content(location.location_code) + expect(page).to have_content("Available from 4 April 2022") + expect(page).to have_content("Active") + end + + it "only allows to edit the location name" do + assert_selector "a", text: "Change", count: 1 + + click_link("Change") expect(page).to have_content "Location name for #{location.postcode}" end + it "allows to deactivate a location" do + click_link("Deactivate this location") + expect(page).to have_current_path("/schemes/#{scheme.id}/locations/#{location.id}/deactivate") + end + context "when I press the back button" do before do click_link "Back" @@ -775,15 +795,27 @@ RSpec.describe "Schemes scheme Features" do context "and I change the location name" do before do - fill_in "location-name-field", with: "NewName" - click_button "Save and continue" + click_link("Change") end it "returns to locations check your answers page and shows the new name" do + fill_in "location-name-field", with: "NewName" + click_button "Save and continue" expect(page).to have_content location.id expect(page).to have_content "NewName" expect(page.current_url.split("/").last).to eq("check-answers#locations") end + + context "when I press the back button" do + before do + click_link "Back" + end + + it "I see location details" do + expect(page).to have_content location.name + expect(page).to have_current_path("/schemes/#{scheme.id}/locations/#{location.id}") + end + end end end diff --git a/spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml b/spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml index 59c1eada7..3faacf28b 100644 --- a/spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml +++ b/spec/fixtures/imports/logs/0b4a68df-30cc-474a-93c0-a56ce8fdad3b.xml @@ -19,7 +19,7 @@
123456
2 Local Authority - <_1cmangroupcode>123 + <_1cmangroupcode>0123 <_1cschemecode>10 3 No diff --git a/spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml b/spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml index 5a7b23b5b..712d3f6e5 100644 --- a/spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml +++ b/spec/fixtures/imports/mgmtgroups/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml @@ -5,5 +5,5 @@ 456 7c5bd5fb549c09z2c55d9cb90d7ba84927e64618 Approved - 123 + 0123 diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index 402772dec..f2a5a67a5 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/spec/helpers/locations_helper_spec.rb @@ -46,4 +46,31 @@ RSpec.describe LocationsHelper do expect(selection_options(%w[example])).to eq([OpenStruct.new(id: "example", name: "Example")]) end end + + describe "display_attributes" do + let(:location) { FactoryBot.build(:location, startdate: Time.zone.local(2022, 8, 8)) } + + it "returns correct display attributes" do + attributes = [ + { name: "Postcode", value: location.postcode }, + { name: "Local authority", value: location.location_admin_district }, + { name: "Location name", value: location.name, edit: true }, + { name: "Total number of units at this location", value: location.units }, + { name: "Common type of unit", value: location.type_of_unit }, + { name: "Mobility type", value: location.mobility_type }, + { name: "Code", value: location.location_code }, + { name: "Availability", value: "Available from 8 August 2022" }, + { name: "Status", value: :active }, + ] + + expect(display_attributes(location)).to eq(attributes) + end + + it "displays created_at as availability date if startdate is not present" do + location.update!(startdate: nil) + availability_attribute = display_attributes(location).find { |x| x[:name] == "Availability" }[:value] + + expect(availability_attribute).to eq("Available from #{location.created_at.to_formatted_s(:govuk_date)}") + end + end end diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index 81a9b1c45..c6a47c107 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -118,6 +118,10 @@ RSpec.describe FormHandler do it "returns the correct next sales form name" do expect(form_handler.form_name_from_start_year(2023, "sales")).to eq("next_sales") end + + it "returns the correct current start date" do + expect(form_handler.current_collection_start_date).to eq(Time.utc(2022, 4, 1)) + end end context "with the date before 1st of April" do diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 856575932..8f9f452bc 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -111,4 +111,36 @@ RSpec.describe Location, type: :model do end end end + + describe "status" do + let(:location) { FactoryBot.build(:location) } + + before do + Timecop.freeze(2022, 6, 7) + end + + it "returns active if the location is not deactivated" do + location.deactivation_date = nil + location.save! + expect(location.status).to eq(:active) + end + + it "returns deactivating soon if deactivation_date is in the future" do + location.deactivation_date = Time.zone.local(2022, 8, 8) + location.save! + expect(location.status).to eq(:deactivating_soon) + end + + it "returns deactivated if deactivation_date is in the past" do + location.deactivation_date = Time.zone.local(2022, 4, 8) + location.save! + expect(location.status).to eq(:deactivated) + end + + it "returns deactivated if deactivation_date is today" do + location.deactivation_date = Time.zone.local(2022, 6, 7) + location.save! + expect(location.status).to eq(:deactivated) + end + end end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index c4c4958db..0b88fdd76 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -18,6 +18,8 @@ RSpec.describe Validations::FinancialValidations do financial_validator.validate_net_income(record) expect(record.errors["incfreq"]) .to include(match I18n.t("validations.financial.earnings.freq_missing")) + expect(record.errors["earnings"]) + .to include(match I18n.t("validations.financial.earnings.freq_missing")) end it "when income frequency is provided it validates that earnings must be provided" do @@ -26,6 +28,8 @@ RSpec.describe Validations::FinancialValidations do financial_validator.validate_net_income(record) expect(record.errors["earnings"]) .to include(match I18n.t("validations.financial.earnings.earnings_missing")) + expect(record.errors["incfreq"]) + .to include(match I18n.t("validations.financial.earnings.earnings_missing")) end end @@ -1010,6 +1014,8 @@ RSpec.describe Validations::FinancialValidations do financial_validator.validate_care_home_charges(record) expect(record.errors["chcharge"]) .to include(match I18n.t("validations.financial.carehome.not_provided", period: "every 4 weeks")) + expect(record.errors["is_carehome"]) + .to include(match I18n.t("validations.financial.carehome.not_provided", period: "every 4 weeks")) end end diff --git a/spec/models/validations/property_validations_spec.rb b/spec/models/validations/property_validations_spec.rb index 153934ebc..b3965b3d6 100644 --- a/spec/models/validations/property_validations_spec.rb +++ b/spec/models/validations/property_validations_spec.rb @@ -233,6 +233,17 @@ RSpec.describe Validations::PropertyValidations do property_validator.validate_rsnvac(record) expect(record.errors["rsnvac"]).to be_empty end + + context "when the letting is not a renewal" do + it "validates that the reason for vacancy is not renewal" do + record.first_time_property_let_as_social_housing = 0 + record.renewal = 0 + record.rsnvac = 14 + property_validator.validate_rsnvac(record) + expect(record.errors["rsnvac"]) + .to include(match I18n.t("validations.property.rsnvac.not_a_renewal")) + end + end end context "when the property has been let before" do diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 96b3d1b21..feeae2b99 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -1212,4 +1212,189 @@ RSpec.describe LocationsController, type: :request do end end end + + describe "#deactivate" do + context "when not signed in" do + it "redirects to the sign in page" do + patch "/schemes/1/locations/1/deactivate" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + patch "/schemes/1/locations/1/deactivate" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } + let!(:location) { FactoryBot.create(:location, scheme:) } + let(:startdate) { Time.utc(2021, 1, 2) } + let(:deactivation_date) { Time.utc(2022, 10, 10) } + + before do + Timecop.freeze(Time.utc(2022, 10, 10)) + sign_in user + patch "/schemes/#{scheme.id}/locations/#{location.id}/deactivate", params: + end + + context "with default date" do + let(:params) { { location: { deactivation_date_type: "default" } } } + + it "renders the confirmation page" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("This change will affect #{location.lettings_logs.count} logs") + end + end + + context "with other date" do + let(:params) { { location: { deactivation_date: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } + + it "renders the confirmation page" do + expect(response).to have_http_status(:ok) + expect(page).to have_content("This change will affect #{location.lettings_logs.count} logs") + end + end + + context "when confirming deactivation" do + let(:params) { { location: { deactivation_date:, confirm: true } } } + + it "updates existing location with valid deactivation date and renders location page" do + follow_redirect! + expect(response).to have_http_status(:ok) + expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") + location.reload + expect(location.deactivation_date).to eq(deactivation_date) + end + end + + context "when the date is not selected" do + let(:params) { { location: { "deactivation_date": "" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.not_selected")) + end + end + + context "when invalid date is entered" do + let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.invalid")) + end + end + + context "when the date is entered is before the beginning of current collection window" do + let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } + + it "displays the new page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.out_of_range", date: "1 April 2022")) + end + end + + context "when the day is not entered" do + let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.not_entered", period: "day")) + end + end + + context "when the month is not entered" do + let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.not_entered", period: "month")) + end + end + + context "when the year is not entered" do + let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } + + it "displays page with an error message" do + expect(response).to have_http_status(:unprocessable_entity) + expect(page).to have_content(I18n.t("validations.location.deactivation_date.not_entered", period: "year")) + end + end + end + end + + describe "#show" do + context "when not signed in" do + it "redirects to the sign in page" do + get "/schemes/1/locations/1" + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in as a data provider" do + let(:user) { FactoryBot.create(:user) } + + before do + sign_in user + get "/schemes/1/locations/1" + end + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + context "when signed in as a data coordinator" do + let(:user) { FactoryBot.create(:user, :data_coordinator) } + let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } + let!(:location) { FactoryBot.create(:location, scheme:) } + + before do + Timecop.freeze(Time.utc(2022, 10, 10)) + sign_in user + location.deactivation_date = deactivation_date + location.save! + get "/schemes/#{scheme.id}/locations/#{location.id}" + end + + context "with active location" do + let(:deactivation_date) { nil } + + it "renders deactivate this location" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Deactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/deactivate") + end + end + + context "with deactivated location" do + let(:deactivation_date) { Time.utc(2022, 10, 9) } + + it "renders reactivate this location" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/reactivate") + end + end + + context "with location that's deactivating soon" do + let(:deactivation_date) { Time.utc(2022, 10, 12) } + + it "renders reactivate this location" do + expect(response).to have_http_status(:ok) + expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/reactivate") + end + end + end + end end diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb index 576249971..453ee7e30 100644 --- a/spec/services/imports/lettings_logs_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_import_service_spec.rb @@ -11,8 +11,8 @@ RSpec.describe Imports::LettingsLogsImportService do let(:fixture_directory) { "spec/fixtures/imports/logs" } let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } - let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: 123, owning_organisation: organisation) } - let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: 456, owning_organisation: organisation) } + let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) } + let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) } def open_file(directory, filename) File.open("#{directory}/#{filename}.xml") @@ -23,16 +23,16 @@ RSpec.describe Imports::LettingsLogsImportService do .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {}) allow(Organisation).to receive(:find_by).and_return(nil) - allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id.to_i).and_return(organisation) + allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation) # Created by users FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:) FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:) # Location setup - FactoryBot.create(:location, old_visible_id: 10, postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W") + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W") FactoryBot.create(:location, scheme_id: scheme1.id) - FactoryBot.create(:location, old_visible_id: 10, postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W") + FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W") # Stub the form handler to use the real form allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form) diff --git a/spec/services/imports/organisation_import_service_spec.rb b/spec/services/imports/organisation_import_service_spec.rb index 48a0d72bb..c8fcd4829 100644 --- a/spec/services/imports/organisation_import_service_spec.rb +++ b/spec/services/imports/organisation_import_service_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Imports::OrganisationImportService do it "successfully create an organisation with the expected data" do import_service.create_organisations(folder_name) - organisation = Organisation.find_by(old_visible_id: 1) + organisation = Organisation.find_by(old_visible_id: "1") expect(organisation.name).to eq("HA Ltd") expect(organisation.provider_type).to eq("PRP") expect(organisation.phone).to eq("xxxxxxxx") @@ -53,7 +53,7 @@ RSpec.describe Imports::OrganisationImportService do expect(organisation.unspecified_units).to eq(0) expect(organisation.unspecified_units).to eq(0) expect(organisation.old_org_id).to eq("7c5bd5fb549c09z2c55d9cb90d7ba84927e64618") - expect(organisation.old_visible_id).to eq(1) + expect(organisation.old_visible_id).to eq("1") end it "successfully create multiple organisations" do @@ -62,8 +62,8 @@ RSpec.describe Imports::OrganisationImportService do expect(storage_service).to receive(:get_file_io).with(filenames[1]).ordered expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(2) - expect(Organisation).to exist(old_visible_id: 1) - expect(Organisation).to exist(old_visible_id: 2) + expect(Organisation).to exist(old_visible_id: "1") + expect(Organisation).to exist(old_visible_id: "2") end end @@ -86,7 +86,7 @@ RSpec.describe Imports::OrganisationImportService do expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(1) expect { import_service.create_organisations(folder_name) }.to change(Organisation, :count).by(0) - expect(Organisation).to exist(old_visible_id: 1, name: "HA Ltd") + expect(Organisation).to exist(old_visible_id: "1", name: "HA Ltd") end end end diff --git a/spec/services/imports/scheme_import_service_spec.rb b/spec/services/imports/scheme_import_service_spec.rb index efba81a1c..97e9359b5 100644 --- a/spec/services/imports/scheme_import_service_spec.rb +++ b/spec/services/imports/scheme_import_service_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Imports::SchemeImportService do let(:scheme_id) { "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d" } let!(:owning_org) { FactoryBot.create(:organisation, old_org_id: "7c5bd5fb549c09z2c55d9cb90d7ba84927e64618") } - let!(:managing_org) { FactoryBot.create(:organisation, old_visible_id: 456) } + let!(:managing_org) { FactoryBot.create(:organisation, old_visible_id: "456") } def open_file(directory, filename) File.open("#{directory}/#{filename}.xml") @@ -46,7 +46,7 @@ RSpec.describe Imports::SchemeImportService do expect(scheme.owning_organisation).to eq(owning_org) expect(scheme.managing_organisation).to eq(managing_org) expect(scheme.old_id).to eq("6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d") - expect(scheme.old_visible_id).to eq(123) + expect(scheme.old_visible_id).to eq("0123") expect(scheme.service_name).to eq("Management Group") expect(scheme.arrangement_type).to eq("Another organisation") end diff --git a/spec/services/imports/scheme_location_import_service_spec.rb b/spec/services/imports/scheme_location_import_service_spec.rb index 70ff039cd..c11c2ca2d 100644 --- a/spec/services/imports/scheme_location_import_service_spec.rb +++ b/spec/services/imports/scheme_location_import_service_spec.rb @@ -142,7 +142,7 @@ RSpec.describe Imports::SchemeLocationImportService do expect(location.mobility_type).to eq("Fitted with equipment and adaptations") expect(location.type_of_unit).to eq("Bungalow") expect(location.old_id).to eq(first_location_id) - expect(location.old_visible_id).to eq(10) + expect(location.old_visible_id).to eq("10") expect(location.startdate).to eq("1900-01-01") expect(location.scheme).to eq(scheme) end @@ -160,21 +160,6 @@ RSpec.describe Imports::SchemeLocationImportService do expect(location.scheme.confirmed).to be_truthy end - context "and the end date is before the current date" do - before do - Timecop.freeze(2022, 6, 1) - location_xml.at_xpath("//scheme:end-date").content = "2022-05-01" - end - - after { Timecop.unfreeze } - - it "does not create the location" do - expect(logger).to receive(:warn).with("Location with legacy ID 0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e is expired (2022-05-01 00:00:00 +0100), skipping") - expect { location_service.create_scheme_location(location_xml) } - .not_to change(Location, :count) - end - end - context "and we import the same location twice" do before { location_service.create_scheme_location(location_xml) }