OSDN Git Service

Ability to remove enumerations (activities, priorities, document categories) that...
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 17 Jun 2008 19:10:54 +0000 (19:10 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 17 Jun 2008 19:10:54 +0000 (19:10 +0000)
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1558 e93f8b46-1217-0410-a6f0-8f06a7374b81

33 files changed:
app/controllers/enumerations_controller.rb
app/models/enumeration.rb
app/views/enumerations/destroy.rhtml [new file with mode: 0644]
app/views/enumerations/list.rhtml
lang/bg.yml
lang/cs.yml
lang/da.yml
lang/de.yml
lang/en.yml
lang/es.yml
lang/fi.yml
lang/fr.yml
lang/he.yml
lang/hu.yml
lang/it.yml
lang/ja.yml
lang/ko.yml
lang/lt.yml
lang/nl.yml
lang/no.yml
lang/pl.yml
lang/pt-br.yml
lang/pt.yml
lang/ro.yml
lang/ru.yml
lang/sr.yml
lang/sv.yml
lang/th.yml
lang/uk.yml
lang/zh-tw.yml
lang/zh.yml
test/functional/enumerations_controller.rb [new file with mode: 0644]
test/unit/enumeration_test.rb [new file with mode: 0644]

index 7a7f168..788fa11 100644 (file)
@@ -75,11 +75,20 @@ class EnumerationsController < ApplicationController
   end
   
   def destroy
-    Enumeration.find(params[:id]).destroy
-    flash[:notice] = l(:notice_successful_delete)
-    redirect_to :action => 'list'
-  rescue
-    flash[:error] = "Unable to delete enumeration"
-    redirect_to :action => 'list'
+    @enumeration = Enumeration.find(params[:id])
+    if !@enumeration.in_use?
+      # No associated objects
+      @enumeration.destroy
+      redirect_to :action => 'index'
+    elsif params[:reassign_to_id]
+      if reassign_to = Enumeration.find_by_opt_and_id(@enumeration.opt, params[:reassign_to_id])
+        @enumeration.destroy(reassign_to)
+        redirect_to :action => 'index'
+      end
+    end
+    @enumerations = Enumeration.get_values(@enumeration.opt) - [@enumeration]
+  #rescue
+  #  flash[:error] = 'Unable to delete enumeration'
+  #  redirect_to :action => 'index'
   end
 end
index e867687..d32a0c0 100644 (file)
@@ -24,10 +24,11 @@ class Enumeration < ActiveRecord::Base
   validates_uniqueness_of :name, :scope => [:opt]
   validates_length_of :name, :maximum => 30
 
+  # Single table inheritance would be an option
   OPTIONS = {
-    "IPRI" => :enumeration_issue_priorities,
-    "DCAT" => :enumeration_doc_categories,
-    "ACTI" => :enumeration_activities
+    "IPRI" => {:label => :enumeration_issue_priorities, :model => Issue, :foreign_key => :priority_id},
+    "DCAT" => {:label => :enumeration_doc_categories, :model => Document, :foreign_key => :category_id},
+    "ACTI" => {:label => :enumeration_activities, :model => TimeEntry, :foreign_key => :activity_id}
   }.freeze
   
   def self.get_values(option)
@@ -39,13 +40,32 @@ class Enumeration < ActiveRecord::Base
   end
 
   def option_name
-    OPTIONS[self.opt]
+    OPTIONS[self.opt][:label]
   end
 
   def before_save
     Enumeration.update_all("is_default = #{connection.quoted_false}", {:opt => opt}) if is_default?
   end
   
+  def objects_count
+    OPTIONS[self.opt][:model].count(:conditions => "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
+  end
+  
+  def in_use?
+    self.objects_count != 0
+  end
+  
+  alias :destroy_without_reassign :destroy
+  
+  # Destroy the enumeration
+  # If a enumeration is specified, objects are reassigned
+  def destroy(reassign_to = nil)
+    if reassign_to && reassign_to.is_a?(Enumeration)
+      OPTIONS[self.opt][:model].update_all("#{OPTIONS[self.opt][:foreign_key]} = #{reassign_to.id}", "#{OPTIONS[self.opt][:foreign_key]} = #{id}")
+    end
+    destroy_without_reassign
+  end
+  
   def <=>(enumeration)
     position <=> enumeration.position
   end
@@ -54,13 +74,6 @@ class Enumeration < ActiveRecord::Base
   
 private
   def check_integrity
-    case self.opt
-    when "IPRI"
-      raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
-    when "DCAT"
-      raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
-    when "ACTI"
-      raise "Can't delete enumeration" if TimeEntry.find(:first, :conditions => ["activity_id=?", self.id])
-    end
+    raise "Can't delete enumeration" if self.in_use?
   end
 end
diff --git a/app/views/enumerations/destroy.rhtml b/app/views/enumerations/destroy.rhtml
new file mode 100644 (file)
index 0000000..657df83
--- /dev/null
@@ -0,0 +1,12 @@
+<h2><%= l(@enumeration.option_name) %>: <%=h @enumeration %></h2>
+
+<% form_tag({}) do %>
+<div class="box">
+<p><strong><%= l(:text_enumeration_destroy_question, @enumeration.objects_count) %></strong></p>
+<p><%= l(:text_enumeration_category_reassign_to) %>
+<%= select_tag 'reassign_to_id', ("<option>--- #{l(:actionview_instancetag_blank_option)} ---</option>" + options_from_collection_for_select(@enumerations, 'id', 'name')) %></p>
+</div>
+
+<%= submit_tag l(:button_apply) %>
+<%= link_to l(:button_cancel), :controller => 'enumerations', :action => 'index' %>
+<% end %>
index 1967e5c..7f3886b 100644 (file)
@@ -1,7 +1,7 @@
 <h2><%=l(:label_enumerations)%></h2>
 
-<% Enumeration::OPTIONS.each do |option, name| %>
-<h3><%= l(name) %></h3>
+<% Enumeration::OPTIONS.each do |option, params| %>
+<h3><%= l(params[:label]) %></h3>
 
 <% enumerations = Enumeration.get_values(option) %>
 <% if enumerations.any? %>
@@ -16,6 +16,9 @@
     <%= link_to image_tag('1downarrow.png', :alt => l(:label_sort_lower)), {:action => 'move', :id => enumeration, :position => 'lower'}, :method => :post, :title => l(:label_sort_lower) %>
     <%= link_to image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), {:action => 'move', :id => enumeration, :position => 'lowest'}, :method => :post, :title => l(:label_sort_lowest) %>
     </td>
+    <td align="center" style="width:10%;">
+    <%= link_to l(:button_delete), { :action => 'destroy', :id => enumeration }, :method => :post, :confirm => l(:text_are_you_sure), :class => "icon icon-del" %>
+    </td>
 </tr>
 <% end %>
 </table>
index 5f35486..48226c7 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 26e0f51..de460ba 100644 (file)
@@ -629,3 +629,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index b2f18db..6919cdf 100644 (file)
@@ -626,3 +626,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 1e4040f..290acd9 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index b7f217e..ffbd106 100644 (file)
@@ -599,6 +599,8 @@ text_destroy_time_entries: Delete reported hours
 text_assign_time_entries_to_project: Assign reported hours to the project
 text_reassign_time_entries: 'Reassign reported hours to this issue:'
 text_user_wrote: '%s wrote:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
 
 default_role_manager: Manager
 default_role_developper: Developer
index c0ecb99..b027f48 100644 (file)
@@ -627,3 +627,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 6ac4aea..e1d188d 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 4db2f8f..eaae517 100644 (file)
@@ -599,6 +599,8 @@ text_destroy_time_entries: Supprimer les heures
 text_assign_time_entries_to_project: Reporter les heures sur le projet
 text_reassign_time_entries: 'Reporter les heures sur cette demande:'
 text_user_wrote: '%s a écrit:'
+text_enumeration_destroy_question: 'Cette valeur est affectée à %d objets.'
+text_enumeration_category_reassign_to: 'Réaffecter les objets à cette valeur:'
 
 default_role_manager: Manager
 default_role_developper: Développeur
index e23698d..5f14ee1 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 1df0619..c46d0e2 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d feladat határidős az elkövetkező napokban"
 text_user_wrote: '%s írta:'
 label_duplicated_by: duplikálta
 setting_enabled_scm: Forráskódkezelő (SCM) engedélyezése
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 5ab9ad3..8aec9ef 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index c693d68..c48579d 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index af1c768..f233955 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index ff8f6b6..61533b3 100644 (file)
@@ -626,3 +626,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 9ee9138..109d444 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index aa9d039..4e47c75 100644 (file)
@@ -625,3 +625,5 @@ default_activity_development: Utvikling
 enumeration_issue_priorities: Sakssprioriteringer
 enumeration_doc_categories: Dokument-kategorier
 enumeration_activities: Aktiviteter (tidssporing)
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 75e04ec..97378b5 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index dabab5b..6782249 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'\r
 label_duplicated_by: duplicated by\r
 setting_enabled_scm: Enabled SCM\r
+text_enumeration_category_reassign_to: 'Reassign them to this value:'\r
+text_enumeration_destroy_question: '%d objects are assigned to this value.'\r
index 2845f39..a91eea0 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index dd51e59..aafc619 100644 (file)
@@ -624,3 +624,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index c3ec918..e043777 100644 (file)
@@ -628,3 +628,5 @@ mail_subject_reminder: "%d назначенных на вас задач в бл
 text_user_wrote: '%s написал:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 9290676..ec01774 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index f08e45e..e28943d 100644 (file)
@@ -625,3 +625,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 85a1f8c..6c84dba 100644 (file)
@@ -627,3 +627,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index ae8c5cb..365ced1 100644 (file)
@@ -626,3 +626,5 @@ mail_subject_reminder: "%d issue(s) due in the next days"
 text_user_wrote: '%s wrote:'
 label_duplicated_by: duplicated by
 setting_enabled_scm: Enabled SCM
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index 064004c..c7b4735 100644 (file)
@@ -625,3 +625,5 @@ default_activity_development: 開發
 enumeration_issue_priorities: 項目優先權
 enumeration_doc_categories: 文件分類
 enumeration_activities: 活動 (時間追蹤)
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
index ac650c8..981e810 100644 (file)
@@ -625,3 +625,5 @@ default_activity_development: 开发
 enumeration_issue_priorities: 问题优先级
 enumeration_doc_categories: 文档类别
 enumeration_activities: 活动(时间跟踪)
+text_enumeration_category_reassign_to: 'Reassign them to this value:'
+text_enumeration_destroy_question: '%d objects are assigned to this value.'
diff --git a/test/functional/enumerations_controller.rb b/test/functional/enumerations_controller.rb
new file mode 100644 (file)
index 0000000..36ff867
--- /dev/null
@@ -0,0 +1,61 @@
+# redMine - project management software
+# Copyright (C) 2006-2008  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'
+require 'enumerations_controller'
+
+# Re-raise errors caught by the controller.
+class EnumerationsController; def rescue_action(e) raise e end; end
+
+class EnumerationsControllerTest < Test::Unit::TestCase
+  fixtures :enumerations, :issues, :users
+  
+  def setup
+    @controller = EnumerationsController.new
+    @request    = ActionController::TestRequest.new
+    @response   = ActionController::TestResponse.new
+    @request.session[:user_id] = 1 # admin
+  end
+
+  def test_index
+    get :index
+    assert_response :success
+    assert_template 'list'
+  end
+  
+  def test_destroy_enumeration_not_in_use
+    post :destroy, :id => 7
+    assert_redirected_to :controller => 'enumerations', :action => 'index'
+    assert_nil Enumeration.find_by_id(7)
+  end
+  
+  def test_destroy_enumeration_in_use
+    post :destroy, :id => 4
+    assert_response :success
+    assert_template 'destroy'
+    assert_not_nil Enumeration.find_by_id(4)
+  end
+  
+  def test_destroy_enumeration_in_use_with_reassignment
+    issue = Issue.find(:first, :conditions => {:priority_id => 4})
+    post :destroy, :id => 4, :reassign_to_id => 6
+    assert_redirected_to :controller => 'enumerations', :action => 'index'
+    assert_nil Enumeration.find_by_id(4)
+    # check that the issue was reassign
+    assert_equal 6, issue.reload.priority_id
+  end
+end
diff --git a/test/unit/enumeration_test.rb b/test/unit/enumeration_test.rb
new file mode 100644 (file)
index 0000000..9b7bfd1
--- /dev/null
@@ -0,0 +1,45 @@
+# redMine - project management software
+# Copyright (C) 2006-2008  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 EnumerationTest < Test::Unit::TestCase
+  fixtures :enumerations, :issues
+
+  def setup
+  end
+  
+  def test_objects_count
+    # low priority
+    assert_equal 5, Enumeration.find(4).objects_count
+    # urgent
+    assert_equal 0, Enumeration.find(7).objects_count
+  end
+  
+  def test_in_use
+    # low priority
+    assert Enumeration.find(4).in_use?
+    # urgent
+    assert !Enumeration.find(7).in_use?
+  end
+  
+  def test_destroy_with_reassign
+    Enumeration.find(4).destroy(Enumeration.find(6))
+    assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
+    assert_equal 5, Enumeration.find(6).objects_count
+  end
+end