diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index 29a3f02a..2c1c6657 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -18,6 +18,8 @@ class IssueCategoriesController < ApplicationController layout 'base' before_filter :find_project, :authorize + + verify :method => :post, :only => :destroy def edit if request.post? and @category.update_attributes(params[:category]) @@ -27,11 +29,17 @@ class IssueCategoriesController < ApplicationController end def destroy - @category.destroy - redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project - rescue - flash[:error] = "Categorie can't be deleted" - redirect_to :controller => 'projects', :action => 'settings', :tab => 'categories', :id => @project + @issue_count = @category.issues.size + if @issue_count == 0 + # No issue assigned to this category + @category.destroy + redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' + elsif params[:todo] + reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id]) if params[:todo] == 'reassign' + @category.destroy(reassign_to) + redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' + end + @categories = @project.issue_categories - [@category] end private diff --git a/app/models/issue_category.rb b/app/models/issue_category.rb index fb2c099a..1abcf4c3 100644 --- a/app/models/issue_category.rb +++ b/app/models/issue_category.rb @@ -16,15 +16,21 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class IssueCategory < ActiveRecord::Base - before_destroy :check_integrity belongs_to :project belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id' - + has_many :issues, :foreign_key => 'category_id', :dependent => :nullify + validates_presence_of :name validates_uniqueness_of :name, :scope => [:project_id] -private - def check_integrity - raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id]) + alias :destroy_without_reassign :destroy + + # Destroy the category + # If a category is specified, issues are reassigned to this category + def destroy(reassign_to = nil) + if reassign_to && reassign_to.is_a?(IssueCategory) && reassign_to.project == self.project + Issue.update_all("category_id = #{reassign_to.id}", "category_id = #{id}") + end + destroy_without_reassign end end diff --git a/app/views/issue_categories/destroy.rhtml b/app/views/issue_categories/destroy.rhtml new file mode 100644 index 00000000..a563736e --- /dev/null +++ b/app/views/issue_categories/destroy.rhtml @@ -0,0 +1,15 @@ +

<%=l(:label_issue_category)%>: <%=h @category.name %>

+ +<% form_tag({}) do %> +
+

<%= l(:text_issue_category_destroy_question, @issue_count) %>

+

<%= radio_button_tag 'todo', 'nullify', true %> <%= l(:text_issue_category_destroy_assignments) %>
+<% if @categories.size > 0 %> +<%= radio_button_tag 'todo', 'reassign', false %> <%= l(:text_issue_category_reassign_to) %>: +<%= select_tag 'reassign_to_id', options_from_collection_for_select(@categories, 'id', 'name') %>

+<% end %> +
+ +<%= submit_tag l(:button_apply) %> +<%= link_to l(:button_cancel), :controller => 'projects', :action => 'settings', :id => @project, :tab => 'categories' %> +<% end %> diff --git a/app/views/projects/settings/_issue_categories.rhtml b/app/views/projects/settings/_issue_categories.rhtml index bad330e2..c1e77e9c 100644 --- a/app/views/projects/settings/_issue_categories.rhtml +++ b/app/views/projects/settings/_issue_categories.rhtml @@ -12,7 +12,7 @@ <%=h(category.name) %> <%=h(category.assigned_to.name) if category.assigned_to %> <%= link_to_if_authorized l(:button_edit), { :controller => 'issue_categories', :action => 'edit', :id => category }, :class => 'icon icon-edit' %> - <%= link_to_if_authorized l(:button_delete), {:controller => 'issue_categories', :action => 'destroy', :id => category}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> + <%= link_to_if_authorized l(:button_delete), {:controller => 'issue_categories', :action => 'destroy', :id => category}, :method => :post, :class => 'icon icon-del' %> <% end %> <% end %> diff --git a/lang/bg.yml b/lang/bg.yml index c3ce4f12..c518f8f9 100644 --- a/lang/bg.yml +++ b/lang/bg.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Отбелязване и приключва text_issue_added: Публикувана е нова задача с номер %s. text_issue_updated: Задача %s е обновена. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Мениджър default_role_developper: Разработчик diff --git a/lang/de.yml b/lang/de.yml index 7e7441dd..88cdbf52 100644 --- a/lang/de.yml +++ b/lang/de.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: Ticket %s wurde erstellt. text_issue_updated: Ticket %s wurde aktualisiert. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Manager default_role_developper: Developer diff --git a/lang/en.yml b/lang/en.yml index f89cfae7..54657069 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: Issue %s has been reported. text_issue_updated: Issue %s has been updated. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Manager default_role_developper: Developer diff --git a/lang/es.yml b/lang/es.yml index 9deecd9a..ad05632a 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: Issue %s has been reported. text_issue_updated: Issue %s has been updated. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Manager default_role_developper: Desarrollador diff --git a/lang/fr.yml b/lang/fr.yml index 852b04f9..0aaf41c4 100644 --- a/lang/fr.yml +++ b/lang/fr.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Référencement et résolution des demandes text_issue_added: La demande %s a été soumise. text_issue_updated: La demande %s a été mise à jour. text_wiki_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce wiki et tout son contenu ? +text_issue_category_destroy_question: Des demandes (%d) sont affectées à cette catégories. Que voulez-vous faire ? +text_issue_category_destroy_assignments: N'affecter les demandes à aucune autre catégorie +text_issue_category_reassign_to: Réaffecter les demandes à cette catégorie default_role_manager: Manager default_role_developper: Développeur diff --git a/lang/it.yml b/lang/it.yml index acaeb65b..49e352ab 100644 --- a/lang/it.yml +++ b/lang/it.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: "E' stata segnalata l'anomalia %s." text_issue_updated: "L'anomalia %s e' stata aggiornata." text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Manager default_role_developper: Sviluppatore diff --git a/lang/ja.yml b/lang/ja.yml index 8134cefa..a59ccaf7 100644 --- a/lang/ja.yml +++ b/lang/ja.yml @@ -480,6 +480,9 @@ text_issues_ref_in_commit_messages: コミットメッセージ内で問題の text_issue_added: 問題 %s が報告されました。 text_issue_updated: 問題 %s が更新されました。 text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: 管理者 default_role_developper: 開発者 diff --git a/lang/nl.yml b/lang/nl.yml index 75c2996a..41123390 100644 --- a/lang/nl.yml +++ b/lang/nl.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Opzoeken en aanpassen van issues in commit b text_issue_added: Issue %s is gerapporteerd. text_issue_updated: Issue %s is gewijzigd. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Manager default_role_developper: Ontwikkelaar diff --git a/lang/pt-br.yml b/lang/pt-br.yml index dd61d3ed..229abe83 100644 --- a/lang/pt-br.yml +++ b/lang/pt-br.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: Tarefa %s foi incluída. text_issue_updated: Tarefa %s foi alterada. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Analista de Negocio ou Gerente de Projeto default_role_developper: Desenvolvedor diff --git a/lang/pt.yml b/lang/pt.yml index fad533d3..7d7cedaf 100644 --- a/lang/pt.yml +++ b/lang/pt.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referenciando e arrumando tarefas nas mensag text_issue_added: Tarefa %s foi incluída. text_issue_updated: Tarefa %s foi alterada. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Analista de Negócio ou Gerente de Projeto default_role_developper: Desenvolvedor diff --git a/lang/sv.yml b/lang/sv.yml index 7244f86e..2196799d 100644 --- a/lang/sv.yml +++ b/lang/sv.yml @@ -479,6 +479,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: Brist %s har rapporterats. text_issue_updated: Brist %s har uppdaterats. text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: Förvaltare default_role_developper: Utvecklare diff --git a/lang/zh.yml b/lang/zh.yml index bdce4ebb..deb9ee41 100644 --- a/lang/zh.yml +++ b/lang/zh.yml @@ -481,6 +481,9 @@ text_issues_ref_in_commit_messages: Referencing and fixing issues in commit mess text_issue_added: %s ѱ text_issue_updated: %s Ѹ text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ? +text_issue_category_destroy_question: Some issues (%d) are assigned to this category. What do you want to do ? +text_issue_category_destroy_assignments: Remove category assignments +text_issue_category_reassign_to: Reassing issues to this category default_role_manager: 管理员 default_role_developper: 开发人员 diff --git a/test/unit/issue_category_test.rb b/test/unit/issue_category_test.rb new file mode 100644 index 00000000..a6edb3c7 --- /dev/null +++ b/test/unit/issue_category_test.rb @@ -0,0 +1,41 @@ +# redMine - project management software +# Copyright (C) 2006-2007 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.dirname(__FILE__) + '/../test_helper' + +class IssueCategoryTest < Test::Unit::TestCase + fixtures :issue_categories, :issues + + def setup + @category = IssueCategory.find(1) + end + + def test_destroy + issue = @category.issues.first + @category.destroy + # Make sure the category was nullified on the issue + assert_nil issue.reload.category + end + + def test_destroy_with_reassign + issue = @category.issues.first + reassign_to = IssueCategory.find(2) + @category.destroy(reassign_to) + # Make sure the issue was reassigned + assert_equal reassign_to, issue.reload.category + end +end