From cc1dac69a39e1bb802d9ed8f81c5c6162cc35ad2 Mon Sep 17 00:00:00 2001 From: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com> Date: Fri, 15 Jul 2022 09:42:35 +0100 Subject: [PATCH] Cldc 1366 add location startdate (#744) * Add location startdate column to the db * Display the schemes with active locations only when selecting a scheme for a case log * When selecting a location for case log, only show active locations * Add startdate to the form * only display the number of active locations in the appended text * Compare date instead of time * Put location questions and hints into a translation file * lint * content change --- app/controllers/locations_controller.rb | 2 +- .../form/setup/questions/location_id.rb | 2 +- app/models/form/setup/questions/scheme_id.rb | 2 +- app/models/scheme.rb | 2 +- app/views/locations/edit.html.erb | 22 +++--- app/views/locations/new.html.erb | 22 +++--- config/locales/en.yml | 16 +++++ .../20220714080044_add_location_startdate.rb | 7 ++ db/schema.rb | 3 +- spec/features/schemes_spec.rb | 47 ++++++++++++ .../form/setup/questions/location_id_spec.rb | 71 ++++++++++++++++++- .../form/setup/questions/scheme_id_spec.rb | 18 ++++- spec/requests/locations_controller_spec.rb | 10 ++- 13 files changed, 193 insertions(+), 31 deletions(-) create mode 100644 db/migrate/20220714080044_add_location_startdate.rb diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index b482b81f0..a2624a790 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -69,7 +69,7 @@ private end def location_params - required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :wheelchair_adaptation, :add_another_location).merge(scheme_id: @scheme.id) + required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :wheelchair_adaptation, :add_another_location, :startdate).merge(scheme_id: @scheme.id) required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode] required_params end diff --git a/app/models/form/setup/questions/location_id.rb b/app/models/form/setup/questions/location_id.rb index fc6e421e1..9e6fb6038 100644 --- a/app/models/form/setup/questions/location_id.rb +++ b/app/models/form/setup/questions/location_id.rb @@ -13,7 +13,7 @@ class Form::Setup::Questions::LocationId < ::Form::Question answer_opts = {} return answer_opts unless ActiveRecord::Base.connected? - Location.select(:id, :postcode, :name).each_with_object(answer_opts) do |location, hsh| + Location.select(:id, :postcode, :name).where("startdate <= ? or startdate IS NULL", Time.zone.today).each_with_object(answer_opts) do |location, hsh| hsh[location.id.to_s] = { "value" => location.postcode, "hint" => location.name } hsh end diff --git a/app/models/form/setup/questions/scheme_id.rb b/app/models/form/setup/questions/scheme_id.rb index e69cd05a3..e758b8444 100644 --- a/app/models/form/setup/questions/scheme_id.rb +++ b/app/models/form/setup/questions/scheme_id.rb @@ -22,7 +22,7 @@ class Form::Setup::Questions::SchemeId < ::Form::Question def displayed_answer_options(case_log) return {} unless case_log.created_by - user_org_scheme_ids = Scheme.select(:id).where(owning_organisation_id: case_log.created_by.organisation_id).map(&:id) + user_org_scheme_ids = Scheme.select(:id).where(owning_organisation_id: case_log.created_by.organisation_id).joins(:locations).merge(Location.where("startdate <= ? or startdate IS NULL", Time.zone.today)).map(&:id) answer_options.select do |k, _v| user_org_scheme_ids.include?(k.to_i) end diff --git a/app/models/scheme.rb b/app/models/scheme.rb index daf7c2564..bdd9671ed 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -148,7 +148,7 @@ class Scheme < ApplicationRecord end def appended_text - "(#{locations.count} locations)" + "(#{locations.count { |location| location.startdate.blank? || location.startdate <= Time.zone.today }} locations)" end def hint diff --git a/app/views/locations/edit.html.erb b/app/views/locations/edit.html.erb index 9227b3efb..227605485 100644 --- a/app/views/locations/edit.html.erb +++ b/app/views/locations/edit.html.erb @@ -16,17 +16,17 @@ <%= f.govuk_text_field :postcode, label: { size: "m" }, - hint: { text: "For example, SW1P 4DF." }, + hint: { text: I18n.t("hints.location.postcode") }, width: 5 %> <%= f.govuk_text_field :name, - label: { text: "Location name (optional)", size: "m" }, - hint: { text: "This is how you refer to this location within your organisation" } %> + label: { text: I18n.t("questions.location.name"), size: "m" }, + hint: { text: I18n.t("hints.location.name") } %> <%= f.govuk_number_field :units, - label: { text: "Total number of units at this location", size: "m" }, + label: { text: I18n.t("questions.location.units"), size: "m" }, width: 2, - hint: { text: "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.s" }, + hint: { text: I18n.t("hints.location.units") }, autofocus: true %> <% type_of_units_selection = Location.type_of_units.keys.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> @@ -34,15 +34,19 @@ type_of_units_selection, :id, :name, - legend: { text: "What is this type of scheme?", size: "m" } %> + legend: { text: I18n.t("questions.location.type_of_unit"), size: "m" } %> <% wheelchair_user_selection = Location.wheelchair_adaptations.keys.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> <%= f.govuk_collection_radio_buttons :wheelchair_adaptation, wheelchair_user_selection, :id, :name, - hint: { text: "This includes stairlifts, ramps, level-access showers or grab rails" }, - legend: { text: "Are the majority of units in this location built or adapted to wheelchair-user standards?", size: "m" } %> + hint: { text: I18n.t("hints.location.wheelchair_adaptation") }, + legend: { text: I18n.t("questions.location.wheelchair_adaptation"), size: "m" } %> + + <%= f.govuk_date_field :startdate, + legend: { text: I18n.t("questions.location.startdate"), size: "m" }, + width: 20 %> <%= govuk_section_break(visible: true, size: "m") %> @@ -52,7 +56,7 @@ :id, :name, inline: true, - legend: { text: "Do you want to add another location?", size: "m" } %> + legend: { text: I18n.t("questions.location.add_another_location"), size: "m" } %> <%= f.hidden_field :page, value: "edit" %> diff --git a/app/views/locations/new.html.erb b/app/views/locations/new.html.erb index 8d964d07c..669a39594 100644 --- a/app/views/locations/new.html.erb +++ b/app/views/locations/new.html.erb @@ -16,17 +16,17 @@ <%= f.govuk_text_field :postcode, label: { size: "m" }, - hint: { text: "For example, SW1P 4DF." }, + hint: { text: I18n.t("hints.location.postcode") }, width: 5 %> <%= f.govuk_text_field :name, - label: { text: "Location name (optional)", size: "m" }, - hint: { text: "This is how you refer to this location within your organisation" } %> + label: { text: I18n.t("questions.location.name"), size: "m" }, + hint: { text: I18n.t("hints.location.name") } %> <%= f.govuk_number_field :units, - label: { text: "Total number of units at this location", size: "m" }, + label: { text: I18n.t("questions.location.units"), size: "m" }, width: 2, - hint: { text: "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.s" }, + hint: { text: I18n.t("hints.location.units") }, autofocus: true %> <% type_of_units_selection = Location.type_of_units.keys.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> @@ -35,7 +35,7 @@ type_of_units_selection, :id, :name, - legend: { text: "What is this type of scheme?", size: "m" } %> + legend: { text: I18n.t("questions.location.type_of_unit"), size: "m" } %> <% wheelchair_user_selection = Location.wheelchair_adaptations.keys.map { |key, _| OpenStruct.new(id: key, name: key.to_s.humanize) } %> @@ -43,8 +43,12 @@ wheelchair_user_selection, :id, :name, - hint: { text: "This includes stairlifts, ramps, level-access showers or grab rails" }, - legend: { text: "Are the majority of units in this location built or adapted to wheelchair-user standards?", size: "m" } %> + hint: { text: I18n.t("hints.location.wheelchair_adaptation") }, + legend: { text: I18n.t("questions.location.wheelchair_adaptation"), size: "m" } %> + + <%= f.govuk_date_field :startdate, + legend: { text: I18n.t("questions.location.startdate"), size: "m" }, + width: 20 %> <%= govuk_section_break(visible: true, size: "m") %> @@ -55,7 +59,7 @@ :id, :name, inline: true, - legend: { text: "Do you want to add another location?", size: "m" } %> + legend: { text: I18n.t("questions.location.add_another_location"), size: "m" } %> <%= f.govuk_submit "Save and continue" %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d27eb0c39..6b5ad6412 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -288,6 +288,22 @@ en: code_required: "Security code is required" code_incorrect: "Security code is incorrect" + questions: + location: + name: "Location name (optional)" + units: "Total number of units at this location" + type_of_unit: "What is this type of scheme?" + wheelchair_adaptation: "Are the majority of units in this location built or adapted to wheelchair-user standards?" + startdate: "When did the first property in this location become available under this scheme?" + add_another_location: "Do you want to add another location?" + + hints: + location: + 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." + wheelchair_adaptation: "This includes stairlifts, ramps, level-access showers or grab rails" + test: one_argument: "This is based on the tenant’s work situation: %{ecstat1}" title_text: diff --git a/db/migrate/20220714080044_add_location_startdate.rb b/db/migrate/20220714080044_add_location_startdate.rb new file mode 100644 index 000000000..9389960c5 --- /dev/null +++ b/db/migrate/20220714080044_add_location_startdate.rb @@ -0,0 +1,7 @@ +class AddLocationStartdate < ActiveRecord::Migration[7.0] + def change + change_table :locations, bulk: true do |t| + t.column :startdate, :datetime + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 60780a3eb..5433ddfcc 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_07_13_095713) do +ActiveRecord::Schema[7.0].define(version: 2022_07_14_080044) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -251,6 +251,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_13_095713) do t.string "old_id" t.integer "old_visible_id" t.string "mobility_type" + t.datetime "startdate", precision: nil t.index ["old_id"], name: "index_locations_on_old_id", unique: true t.index ["scheme_id"], name: "index_locations_on_scheme_id" end diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index cb5dd6770..9230ab143 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -772,4 +772,51 @@ RSpec.describe "Schemes scheme Features" do end end end + + context "when selecting a scheme" do + let!(:user) { FactoryBot.create(:user, :data_coordinator, last_sign_in_at: Time.zone.now) } + let!(:schemes) { FactoryBot.create_list(:scheme, 5, owning_organisation: user.organisation) } + let(:location) { FactoryBot.create(:location, scheme: schemes[2]) } + let!(:case_log) { FactoryBot.create(:case_log, created_by: user, needstype: 2) } + + before do + Timecop.freeze(Time.utc(2022, 6, 3)) + location.update!(startdate: nil) + FactoryBot.create(:location, scheme: schemes[0], startdate: nil) + FactoryBot.create(:location, scheme: schemes[1], startdate: nil) + FactoryBot.create(:location, scheme: schemes[1], startdate: nil) + FactoryBot.create(:location, scheme: schemes[1], startdate: Time.utc(2023, 6, 3)) + visit("/logs") + fill_in("user[email]", with: user.email) + fill_in("user[password]", with: user.password) + click_button("Sign in") + end + + after do + Timecop.unfreeze + end + + it "does not display the schemes without a location" do + visit("/logs/#{case_log.id}/scheme") + expect(find("#case-log-scheme-id-field").all("option").count).to eq(3) + end + + it "does not display the schemes with a location with a startdate in the future" do + location.update!(startdate: Time.utc(2022, 7, 4)) + visit("/logs/#{case_log.id}/scheme") + expect(find("#case-log-scheme-id-field").all("option").count).to eq(2) + end + + it "does display the schemes with a location with a startdate in the past" do + location.update!(startdate: Time.utc(2022, 5, 2)) + visit("/logs/#{case_log.id}/scheme") + expect(find("#case-log-scheme-id-field").all("option").count).to eq(3) + end + + it "does display the schemes with a location with a startdate being today" do + location.update!(startdate: Time.utc(2022, 6, 3)) + visit("/logs/#{case_log.id}/scheme") + expect(find("#case-log-scheme-id-field").all("option").count).to eq(3) + end + end end diff --git a/spec/models/form/setup/questions/location_id_spec.rb b/spec/models/form/setup/questions/location_id_spec.rb index dd1bd9735..c8681810f 100644 --- a/spec/models/form/setup/questions/location_id_spec.rb +++ b/spec/models/form/setup/questions/location_id_spec.rb @@ -31,7 +31,74 @@ RSpec.describe Form::Setup::Questions::LocationId, type: :model do expect(question).not_to be_derived end - it "has the correct answer_options" do - expect(question.answer_options).to eq({}) + context "when there are no locations" do + it "the answer_options is an empty hash" do + expect(question.answer_options).to eq({}) + end + end + + context "when getting available locations" do + let(:scheme) { FactoryBot.create(:scheme) } + let(:case_log) { FactoryBot.create(:case_log, scheme:, needstype: 2) } + + context "when there are no locations" do + it "the displayed_answer_options is an empty hash" do + expect(question.displayed_answer_options(case_log)).to eq({}) + end + end + + context "when selected scheme has locations" do + before do + Timecop.freeze(Time.utc(2022, 5, 12)) + end + + after do + Timecop.unfreeze + end + + context "and all the locations have a future startdate" do + before do + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 13)) + FactoryBot.create(:location, scheme:, startdate: Time.utc(2023, 1, 1)) + end + + it "the displayed_answer_options is an empty hash" do + expect(question.displayed_answer_options(case_log)).to eq({}) + end + end + + context "and the locations have a no startdate" do + before do + FactoryBot.create(:location, scheme:, startdate: nil) + FactoryBot.create(:location, scheme:, startdate: nil) + end + + it "the displayed_answer_options shows the locations" do + expect(question.displayed_answer_options(case_log).count).to eq(2) + end + end + + context "and the locations have a past startdate" do + before do + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 4, 10)) + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12)) + end + + it "the displayed_answer_options shows the locations" do + expect(question.displayed_answer_options(case_log).count).to eq(2) + end + end + + context "and some locations have a past startdate" do + before do + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 10, 10)) + FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 12)) + end + + it "the displayed_answer_options shows the active location" do + expect(question.displayed_answer_options(case_log).count).to eq(1) + end + end + end end end diff --git a/spec/models/form/setup/questions/scheme_id_spec.rb b/spec/models/form/setup/questions/scheme_id_spec.rb index 9dde00b84..2b016f463 100644 --- a/spec/models/form/setup/questions/scheme_id_spec.rb +++ b/spec/models/form/setup/questions/scheme_id_spec.rb @@ -50,9 +50,21 @@ RSpec.describe Form::Setup::Questions::SchemeId, type: :model do FactoryBot.create(:scheme, owning_organisation: organisation_2) end - it "has the correct answer_options based on the schemes the user's organisation owns or manages" do - expected_answer = { scheme.id.to_s => scheme } - expect(question.displayed_answer_options(case_log)).to eq(expected_answer) + context "when a scheme with at least 1 location exists" do + before do + FactoryBot.create(:location, scheme:) + end + + it "has the correct answer_options based on the schemes the user's organisation owns or manages" do + expected_answer = { scheme.id.to_s => scheme } + expect(question.displayed_answer_options(case_log)).to eq(expected_answer) + end + end + + context "when there are no schemes with locations" do + it "returns an empty hash" do + expect(question.displayed_answer_options(case_log)).to eq({}) + end end end end diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index c67b4358a..0f770ddb3 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -90,7 +90,8 @@ RSpec.describe LocationsController, type: :request do 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(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } } + let(:startdate) { Time.utc(2022, 2, 2) } + let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ", startdate: } } } before do sign_in user @@ -111,6 +112,7 @@ RSpec.describe LocationsController, type: :request do expect(Location.last.units).to eq(5) expect(Location.last.type_of_unit).to eq("Bungalow") expect(Location.last.wheelchair_adaptation).to eq("No") + expect(Location.last.startdate).to eq(startdate) end context "when postcode is submitted with lower case" do @@ -389,8 +391,9 @@ RSpec.describe LocationsController, type: :request do 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(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ", page: "edit" } } } + let!(:location) { FactoryBot.create(:location, scheme:) } + let(:startdate) { Time.utc(2021, 1, 2) } + let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ", startdate:, page: "edit" } } } before do sign_in user @@ -410,6 +413,7 @@ RSpec.describe LocationsController, type: :request do expect(Location.last.units).to eq(5) expect(Location.last.type_of_unit).to eq("Bungalow") expect(Location.last.wheelchair_adaptation).to eq("No") + expect(Location.last.startdate).to eq(startdate) end context "when updating from edit-name page" do