diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 9001e92..e05612a 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -4,6 +4,11 @@ Redmine Checklists plugin - managing issue checklists plugin for Redmine Copyright (C) 2011-2024 Kirill Bezrukov (RedmineUP) http://www.redmineup.com/ +== 2024-08-28 v3.1.25 + +* Fixed copying of checklists with bulk copying of issues +* Fixed notifications when changing a checklist and a log at the same time + == 2024-05-27 v3.1.24 * Updated Redmine 5.0 compatibility diff --git a/init.rb b/init.rb index 6ba9b3f..51ce700 100644 --- a/init.rb +++ b/init.rb @@ -19,7 +19,7 @@ requires_redmineup version_or_higher: '1.0.5' rescue raise "\n\033[31mRedmine requires newer redmineup gem version.\nPlease update with 'bundle update redmineup'.\033[0m" -CHECKLISTS_VERSION_NUMBER = '3.1.24'.freeze +CHECKLISTS_VERSION_NUMBER = '3.1.25'.freeze CHECKLISTS_VERSION_TYPE = "Light version" Redmine::Plugin.register :redmine_checklists do diff --git a/lib/redmine_checklists/patches/issue_patch.rb b/lib/redmine_checklists/patches/issue_patch.rb index cf136fd..97ad483 100644 --- a/lib/redmine_checklists/patches/issue_patch.rb +++ b/lib/redmine_checklists/patches/issue_patch.rb @@ -25,14 +25,11 @@ module RedmineChecklists def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do - attr_accessor :old_checklists - attr_accessor :removed_checklist_ids - attr_accessor :checklists_from_params + attr_accessor :old_checklists, :removed_checklist_ids, :checklists_from_params attr_reader :copied_from - alias_method :copy_without_checklist, :copy - alias_method :copy, :copy_with_checklist - after_save :copy_subtask_checklists + alias_method :after_create_from_copy_without_checklists, :after_create_from_copy + alias_method :after_create_from_copy, :after_create_from_copy_with_checklists has_many :checklists, lambda { order("#{Checklist.table_name}.position") }, :class_name => 'Checklist', :dependent => :destroy, :inverse_of => :issue @@ -46,25 +43,14 @@ module RedmineChecklists end module InstanceMethods - def copy_checklists(arg) - issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg) - return unless issue - - issue.checklists.each do |checklist| - Checklist.create(checklist.attributes.except('id', 'issue_id').merge(issue: self)) - end + def copy_checklists + checklists_attributes = copied_from.checklists.map { |checklist| checklist.attributes.dup.except('id', 'issue_id').merge('issue_id' => id) } + checklists.create(checklists_attributes) end - def copy_subtask_checklists - return if checklists_from_params || !copy? || parent_id.nil? || checklists.reload.any? - - copy_checklists(@copied_from) - end - - def copy_with_checklist(attributes = nil, copy_options = {}) - copy = copy_without_checklist(attributes, copy_options) - copy.copy_checklists(self) - copy + def after_create_from_copy_with_checklists + after_create_from_copy_without_checklists + copy_checklists if copy? && checklists.blank? && copied_from.checklists.present? && !checklists_from_params end def all_checklist_items_is_done? diff --git a/lib/redmine_checklists/patches/issues_controller_patch.rb b/lib/redmine_checklists/patches/issues_controller_patch.rb index f007eb7..9ac3d8b 100644 --- a/lib/redmine_checklists/patches/issues_controller_patch.rb +++ b/lib/redmine_checklists/patches/issues_controller_patch.rb @@ -49,10 +49,10 @@ module RedmineChecklists def save_before_state @issue.old_checklists = @issue.checklists.to_json - checklists_params = params[:issue].present? && params[:issue][:checklists_attributes].present? ? params[:issue][:checklists_attributes] : {} + checklists_params = params.dig(:issue, :checklists_attributes) || {} @issue.removed_checklist_ids = if checklists_params.present? - checklists_params = checklists_params.respond_to?(:to_unsafe_hash) ? checklists_params.to_unsafe_hash : checklists_params + checklists_params = checklists_params.to_unsafe_hash if checklists_params.respond_to?(:to_unsafe_hash) checklists_params.map { |_k, v| v['id'].to_i if ['1', 'true'].include?(v['_destroy']) }.compact else [] diff --git a/lib/redmine_checklists/patches/project_patch.rb b/lib/redmine_checklists/patches/project_patch.rb index 66636e9..8bb9c4d 100644 --- a/lib/redmine_checklists/patches/project_patch.rb +++ b/lib/redmine_checklists/patches/project_patch.rb @@ -25,17 +25,10 @@ module RedmineChecklists def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do - alias_method :copy_issues_without_checklist, :copy_issues - alias_method :copy_issues, :copy_issues_with_checklist end end module InstanceMethods - - def copy_issues_with_checklist(project) - copy_issues_without_checklist(project) - issues.each{ |issue| issue.copy_checklists(issue.copied_from) if issue.reload.checklists.empty? } - end end end end diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index f36646b..6b8aba8 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -233,4 +233,42 @@ class IssuesControllerTest < ActionController::TestCase assert_response :success assert_not_include 'changed from [ ] TEST to [x] TEST', response.body end + + def test_bulk_copy_issues_with_checklists + @target_project = Project.find(2) + @target_project.issues.destroy_all + issue1 = Issue.find(1) # issue with checklists + issue3 = Issue.find(3) # issue without checklists + + @request.session[:user_id] = 2 + + assert_difference 'Issue.count', 2 do + assert_no_difference 'Project.find(1).issues.count' do + post( + :bulk_update, + :params => { + :ids => [issue1.id, issue3.id], + :copy => '1', + :issue => { + :project_id => @target_project.id, + :tracker_id => '', + :assigned_to_id => '2', + :status_id => '1' + } + } + ) + end + end + + copied_issues = Issue.where(project_id: @target_project.id) + assert_equal 2, copied_issues.count + copied_issues.each do |issue| + assert_equal @target_project.id, issue.project_id, "Project is incorrect" + assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect" + assert_equal 1, issue.status_id, "Status is incorrect" + end + + issue_with_checklists = copied_issues.select { |issue| issue.checklists.present? }.first + assert_equal issue1.checklists.count, issue_with_checklists.checklists.count + end end