controller_issues_bulk_edit_before_save => how to make as controller_issues_bulk_edit_after_save
Added by Stéphane CHÂTEAU over 3 years ago
For a plugin, I create geometries to be able to georeference issues.
The goal of my problem is to be able to copy these geometries when creating issues. It's done by hooking controller_issues_new_after_save like this:
module xPointeHook
module Hooks
class GeometryIssueHook < Redmine::Hook::Listener
def controller_issues_new_after_save_geometries(context = { })
issue = context[:issue]
if !issue.id.nil? && !issue.project_id.nil?
if context[:params].key?(:copy_from) && !context[:params][:copy_from].nil?
project = Project.find(issue.project_id)
if !project.nil?
#Rails.logger.info("project = " + project.id.to_s + " / name = " + project.name)
#Rails.logger.info("issue source = " + context[:params][:copy_from].to_s)
if is_project_allow_pointe?(project)
# Uniquement si le projet destination autorise les pointés
Pointes.where(issue_id: context[:params][:copy_from]).all.each do |blc_pointe|
pointe = Pointes.new( { :issue_id => issue.id,
:pointe => blc_pointe.pointe.nil? ? nil : blc_pointe.pointe.as_text(),
:point_attendu => blc_pointe.point_attendu.nil? ? nil : blc_pointe.point_attendu.as_text(),
:line_attendu => blc_pointe.line_attendu.nil? ? nil : blc_pointe.line_attendu.as_text(),
:polygon_attendu => blc_pointe.polygon_attendu.nil? ? nil : blc_pointe.polygon_attendu.as_text(),
:state => blc_pointe.state,
:comment => blc_pointe.comment
}
)
pointe.save
end
end
end
end
end
return ''
end
alias_method :controller_issues_new_after_save, :controller_issues_new_after_save_geometries
end
end
end
First I hook controller_issues_new_after_save and then, if the issue is a copy, and have geometries allowed on target project (is_project_allow_pointe?) then I copied Pointes'rows that match to source Issue to new one.
It's work perfectly !
The problem is ... for bulk copy. There are controller_issues_bulk_edit_before_save but no controller_issues_bulk_edit_after_save like asked by some developpers: https://www.redmine.org/issues/8757
I'm neebie on rails.
My question is: is it possible to hook controller_issues_bulk_edit_before_save and then hook on each issue 'after_save' callback with ActiveRecord?
The problem is, I cannot create Pointes.new if I have not the issue id and in controller_issues_bulk_edit_before_save the row is not already saved and the id is nil, so I must wait the issue really saved into database.
May be it's a way to be able to add Pointes rows after issue bulk copy.
Actually I have this code: (same as previous but the specific hook controller_issues_bulk_edit_before_save.
module xPointeHook
module Hooks
class GeometryIssueHook < Redmine::Hook::Listener
def controller_issues_bulk_edit_before_save_geometries(context = { })
if context[:params][:copy].present?
# Uniquement en cas de copie
issue = context[:issue]
Rails.logger.info("issue.id = " + (issue.id.nil? ? "nil" : issue.id.to_s))
Rails.logger.info("issue.project_id = " + (issue.project_id.nil? ? "nil" : issue.project_id.to_s))
context[:params].each do |key, value|
Rails.logger.info("params[#{key}] = #{value}")
end
end
Rails.logger.info(">>>>>>>> issue = #{context[:issue]}")
end
alias_method :controller_issues_bulk_edit_before_save, :controller_issues_bulk_edit_before_save_geometries
end
end
end
It's seems that in params[:ids] there is a list of source ids that allow me to retrieve source issue and then source Pointes rows.
Replies (1)
RE: controller_issues_bulk_edit_before_save => how to make as controller_issues_bulk_edit_after_save
-
Added by Stéphane CHÂTEAU over 3 years ago
It's done by another way:
Controller:
module xPointeHook
module Hooks
class GeometryIssueHook < Redmine::Hook::Listener
def controller_issues_new_before_save_geometries(context = { })
issue = context[:issue]
if !issue.project_id.nil?
if context[:params].key?(:copy_from) && !context[:params][:copy_from].nil? && context[:params].key?(:copy_geometries) && context[:params][:copy_geometries] != "0"
project = Project.find(issue.project_id)
if !project.nil? && is_project_allow_pointe?(project)
# Uniquement si le projet destination autorise les pointés
issue.set_create_pointe_on_save_issue_id_source(context[:params][:copy_from])
end
end
end
return ''
end
def controller_issues_bulk_edit_before_save_geometries(context = { })
if context[:params][:copy].present? && context[:issue].copy? && context[:params].key?(:copy_geometries) && context[:params][:copy_geometries] != "0"
context[:issue].set_create_pointe_on_save_issue_id_source(context[:issue].copy_id)
else
if !check_pointes_states(context)
context[:issue].set_not_allowed_to_be_saved
end
end
end
alias_method :controller_issues_new_before_save, :controller_issues_new_before_save_geometries
alias_method :controller_issues_bulk_edit_before_save, :controller_issues_bulk_edit_before_save_geometries
end
end
end
Patch Issue:
module Geometry::Patches::Models
module IssuePatch
def self.included(base)
base.send :include, InstanceMethods
end
module InstanceMethods
def set_not_allowed_to_be_saved
@can_save = false
end
def set_create_pointe_on_save_issue_id_source(id)
@issue_id_ref = id
end
# Est appelé à chaque fois qu'une FT est sauvée
def save
bRet = false
if @can_save.nil? || @can_save
if !@issue_id_ref.nil?
# Sauvegarde autorisée mais copie des pointés
Issue.transaction do
bRet = super
if bRet
bRet = create_pointe_copy_from
if !bRet
# S'il faut copier les pointés et que ça a échoué
raise ActiveRecord::Rollback
end
end
end
else
# Traitement par défaut de toutes les sauvegarde d'issue
bRet = super
end
else
# Sera remis à false à la prochaine tentative
@can_save = nil
@issue_id_ref = nil
bRet = false
end
bRet
end
# Returns the issue copy id
def copy_id
return copy? ? @copied_from : nil
end
private
# Est appelé à chaque fois qu'une FT est sauvée
def create_pointe_copy_from
bRet = true
if !@issue_id_ref.nil?
issueid = @issue_id_ref
@issue_id_ref = nil
Pointes.where(issue_id: issueid).all.each do |blc_pointe|
pointe = Pointes.new( { :issue_id => self.id,
:pointe => blc_pointe.pointe.nil? ? nil : blc_pointe.pointe.as_text(),
:point_attendu => blc_pointe.point_attendu.nil? ? nil : blc_pointe.point_attendu.as_text(),
:line_attendu => blc_pointe.line_attendu.nil? ? nil : blc_pointe.line_attendu.as_text(),
:polygon_attendu => blc_pointe.polygon_attendu.nil? ? nil : blc_pointe.polygon_attendu.as_text(),
:state => blc_pointe.state,
:comment => blc_pointe.comment
}
)
bRet = pointe.save && bRet
end
end
bRet
end
end # Module InstanceMethods
end # Module IssuePatch
end # Module Geometry
Init.rb: (simplified)
require 'redmine'
# It requires the file in lib/geometry/hooks/geometry_issue_hook.rb
require_dependency 'geometry/hooks/geometry_issue_hook'
Redmine::Plugin.register :geometry do
name ''
author ''
description 'xxx'
version '2.0.0'
url ''
# include file lib/geometry/patches/models/issue_patch.rb file
unless Issue.included_modules.include?(Geometry::Patches::Models::IssuePatch)
Issue.send(:include, Geometry::Patches::Models::IssuePatch)
end
end