diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index 4612e6bc9..dc5a36c9b 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -21,7 +21,7 @@ class OrganisationsController < ApplicationController end def schemes - organisation_schemes = Scheme.where(owning_organisation: [@organisation] + @organisation.parent_organisations) + organisation_schemes = Scheme.visible.where(owning_organisation: [@organisation] + @organisation.parent_organisations) @pagy, @schemes = pagy(filter_manager.filtered_schemes(organisation_schemes, search_term, session_filters)) @searched = search_term.presence diff --git a/app/controllers/schemes_controller.rb b/app/controllers/schemes_controller.rb index 5eec2a294..2e21421f7 100644 --- a/app/controllers/schemes_controller.rb +++ b/app/controllers/schemes_controller.rb @@ -13,11 +13,11 @@ class SchemesController < ApplicationController def index redirect_to schemes_organisation_path(current_user.organisation) unless current_user.support? - all_schemes = Scheme.all + all_visible_schemes = Scheme.all.visible - @pagy, @schemes = pagy(filter_manager.filtered_schemes(all_schemes, search_term, session_filters)) + @pagy, @schemes = pagy(filter_manager.filtered_schemes(all_visible_schemes, search_term, session_filters)) @searched = search_term.presence - @total_count = all_schemes.size + @total_count = all_visible_schemes.size @filter_type = "schemes" end @@ -223,6 +223,11 @@ class SchemesController < ApplicationController def csv_confirmation; end + def delete + @scheme.discard! + redirect_to schemes_organisation_path(@scheme.owning_organisation), notice: I18n.t("notification.scheme_deleted", service_name: @scheme.service_name) + end + private def authorize_user diff --git a/app/models/scheme.rb b/app/models/scheme.rb index 0bfd56373..2518293a0 100644 --- a/app/models/scheme.rb +++ b/app/models/scheme.rb @@ -77,6 +77,8 @@ class Scheme < ApplicationRecord .where.not(id: activating_soon.pluck(:id)) } + scope :visible, -> { where(discarded_at: nil) } + validate :validate_confirmed validate :validate_owning_organisation @@ -229,7 +231,7 @@ class Scheme < ApplicationRecord end def validate_confirmed - required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type startdate] + required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type startdate discarded_at] if confirmed == true required_attributes.any? do |attribute| @@ -264,6 +266,7 @@ class Scheme < ApplicationRecord end def status_at(date) + return :deleted if discarded_at.present? return :incomplete unless confirmed && locations.confirmed.any? return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date @@ -288,4 +291,9 @@ class Scheme < ApplicationRecord def deactivates_in_a_long_time? status_at(6.months.from_now) == :deactivating_soon end + + def discard! + update!(discarded_at: Time.zone.now) + locations.each(&:discard!) + end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9c02a78f7..1f4f27b69 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -197,6 +197,7 @@ en: one: "There is %{count} set of duplicate logs" other: "There are %{count} sets of duplicate logs" location_deleted: "%{postcode} has been deleted." + scheme_deleted: "%{service_name} has been deleted." validations: organisation: diff --git a/db/migrate/20240304100017_add_discarded_at_column_to_schemes.rb b/db/migrate/20240304100017_add_discarded_at_column_to_schemes.rb new file mode 100644 index 000000000..57ced4dee --- /dev/null +++ b/db/migrate/20240304100017_add_discarded_at_column_to_schemes.rb @@ -0,0 +1,5 @@ +class AddDiscardedAtColumnToSchemes < ActiveRecord::Migration[7.0] + def change + add_column :schemes, :discarded_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 7496ba11a..a0c712d51 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: 2024_03_01_125651) do +ActiveRecord::Schema[7.0].define(version: 2024_03_04_100017) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -699,6 +699,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_03_01_125651) do t.integer "total_units" t.boolean "confirmed" t.datetime "startdate" + t.datetime "discarded_at" t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id" end diff --git a/spec/requests/schemes_controller_spec.rb b/spec/requests/schemes_controller_spec.rb index 47714a992..448a4a004 100644 --- a/spec/requests/schemes_controller_spec.rb +++ b/spec/requests/schemes_controller_spec.rb @@ -2710,4 +2710,74 @@ RSpec.describe SchemesController, type: :request do end end end + + describe "#delete" do + let(:scheme) { create(:scheme, service_name: "Scheme to delete", owning_organisation: user.organisation) } + let!(:locations) { create_list(:location, 2, scheme:, created_at: Time.zone.local(2022, 4, 1)) } + + before do + delete "/schemes/#{scheme.id}/delete" + end + + context "when not signed in" do + it "redirects to the sign in page" do + expect(response).to redirect_to("/account/sign-in") + end + end + + context "when signed in" do + before do + allow(user).to receive(:need_two_factor_authentication?).and_return(false) + sign_in user + delete "/schemes/#{scheme.id}/delete" + end + + context "with a data provider user" do + let(:user) { create(:user) } + + it "returns 401 unauthorized" do + expect(response).to have_http_status(:unauthorized) + end + end + + context "with a data coordinator user" do + let(:user) { create(:user, :data_coordinator) } + + it "returns 401 unauthorized" do + expect(response).to have_http_status(:unauthorized) + end + end + + context "with a support user user" do + let(:user) { create(:user, :support) } + + it "deletes the scheme" do + scheme.reload + expect(scheme.status).to eq(:deleted) + expect(scheme.discarded_at).not_to be nil + end + + it "deletes associated locations" do + locations.each do |location| + location.reload + expect(location.status).to eq(:deleted) + expect(location.discarded_at).not_to be nil + end + end + + it "redirects to the schemes list and displays a notice that the scheme has been deleted" do + expect(response).to redirect_to schemes_organisation_path(scheme.owning_organisation) + follow_redirect! + expect(page).to have_selector(".govuk-notification-banner--success") + expect(page).to have_selector(".govuk-notification-banner--success", text: "Scheme to delete has been deleted.") + end + + it "does not display the deleted scheme" do + expect(response).to redirect_to schemes_organisation_path(scheme.owning_organisation) + follow_redirect! + expect(page).not_to have_link("Scheme to delete") + end + end + end + end end