diff --git a/app/controllers/product_drives_controller.rb b/app/controllers/product_drives_controller.rb index 05e55e5dca..67c24a268d 100644 --- a/app/controllers/product_drives_controller.rb +++ b/app/controllers/product_drives_controller.rb @@ -1,6 +1,7 @@ class ProductDrivesController < ApplicationController include Importable before_action :set_product_drive, only: [:show, :edit, :update, :destroy] + before_action :verify_role, only: :destroy def index setup_date_range_picker @@ -76,7 +77,15 @@ def update end def destroy - current_organization.product_drives.find(params[:id]).destroy + product_drive = current_organization.product_drives.find(params[:id]) + product_drive.destroy + + if product_drive.errors.any? + flash[:error] = product_drive.errors.full_messages.join("\n") + redirect_back(fallback_location: product_drives_url) + return + end + respond_to do |format| format.html { redirect_to product_drives_url, notice: 'Product drive was successfully destroyed.' } format.json { head :no_content } @@ -85,6 +94,13 @@ def destroy private + def verify_role + return if current_user.has_role?(Role::ORG_ADMIN, current_organization) + + flash[:error] = 'You are not allowed to perform this action.' + redirect_to product_drives_url + end + # Use callbacks to share common setup or constraints between actions. def set_product_drive @product_drive_info = ProductDrive.find(params[:id]) diff --git a/app/helpers/product_drive_helper.rb b/app/helpers/product_drive_helper.rb index f6dd0c3784..f5b857ab81 100644 --- a/app/helpers/product_drive_helper.rb +++ b/app/helpers/product_drive_helper.rb @@ -4,4 +4,8 @@ def is_virtual(product_drive:) product_drive.virtual? ? 'Yes' : 'No' end + + def can_delete_product_drive?(user, product_drive) + user.has_role?(Role::ORG_ADMIN, product_drive.organization) && product_drive.donations.empty? + end end diff --git a/app/models/product_drive.rb b/app/models/product_drive.rb index f9a36a4b87..77353e8e27 100644 --- a/app/models/product_drive.rb +++ b/app/models/product_drive.rb @@ -40,6 +40,8 @@ class ProductDrive < ApplicationRecord validate :end_date_is_bigger_of_end_date + before_destroy :validate_destroy, prepend: true + def end_date_is_bigger_of_end_date return if start_date.nil? || end_date.nil? @@ -69,6 +71,13 @@ def self.search_date_range(dates) @search_date_range = { start_date: dates[0], end_date: dates[1] } end + def validate_destroy + return if donations.empty? + + errors.add(:base, "Cannot delete product drive with donations.") + throw(:abort) + end + # quantities are FILTERED by date then SORTED by name # # @param date_range [Range] diff --git a/app/views/product_drives/show.html.erb b/app/views/product_drives/show.html.erb index 4153457f04..f663d4cbeb 100644 --- a/app/views/product_drives/show.html.erb +++ b/app/views/product_drives/show.html.erb @@ -90,7 +90,10 @@

diff --git a/spec/requests/product_drives_requests_spec.rb b/spec/requests/product_drives_requests_spec.rb index fe6f4476ea..9e5223413c 100644 --- a/spec/requests/product_drives_requests_spec.rb +++ b/spec/requests/product_drives_requests_spec.rb @@ -209,11 +209,37 @@ end describe "DELETE #destroy" do - it "redirects to the index" do - product_drive = create(:product_drive, organization: organization) + let(:product_drive) { create(:product_drive, organization: organization) } + + context 'when user is not a org_admin' do + it "does not delete the product drive" do + delete product_drive_path(id: product_drive.id) + follow_redirect! + + expect(response.body).to include('You are not allowed to perform this action.') + end + end + + context 'when user is a org_admin' do + before do + user.add_role(Role::ORG_ADMIN, organization) + end + + it 'deletes the product drive' do + delete product_drive_path(id: product_drive.id) + follow_redirect! + + expect(response.body).to include('Product drive was successfully destroyed.') + end + + it "does not delete the product drive if it has donations" do + user.add_role(Role::ORG_ADMIN, organization) + create(:donation, product_drive: product_drive) + delete product_drive_path(id: product_drive.id) + follow_redirect! - delete product_drive_path(id: product_drive.id) - expect(response).to redirect_to(product_drives_path) + expect(response.body).to include('Cannot delete product drive with donations.') + end end end end