suitepro/plugins/additionals/lib/additionals/patches/issue_patch.rb

192 lines
6.9 KiB
Ruby
Executable file

module Additionals
module Patches
module IssuePatch
extend ActiveSupport::Concern
included do
include InstanceMethods
alias_method :editable_without_additionals?, :editable?
alias_method :editable?, :editable_with_additionals?
validate :validate_change_on_closed
validate :validate_timelog_required
validate :validate_current_user_status
before_validation :auto_assigned_to
before_save :change_status_with_assigned_to_change,
:autowatch_involved
safe_attributes 'author_id',
if: proc { |issue, user|
issue.new_record? && user.allowed_to?(:change_new_issue_author, issue.project) ||
issue.persisted? && user.allowed_to?(:edit_issue_author, issue.project)
}
end
class_methods do
def join_issue_status(options = {})
sql = "JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{table_name}.status_id"
return sql unless options.key?(:is_closed)
sql << " AND #{IssueStatus.table_name}.is_closed ="
sql << if options[:is_closed]
" #{connection.quoted_true}"
else
" #{connection.quoted_false}"
end
sql
end
end
module InstanceMethods
def sidbar_change_status_allowed_to(user, new_status_id = nil)
statuses = new_statuses_allowed_to(user)
if new_status_id.present?
statuses.detect { |s| new_status_id == s.id && !timelog_required?(s.id) }
else
statuses.reject { |s| timelog_required?(s.id) }
end
end
def add_autowatcher(watcher)
return if watcher.nil? ||
!watcher.is_a?(User) ||
watcher.anonymous? ||
!watcher.active? ||
watched_by?(watcher)
add_watcher watcher
end
def autowatch_involved
return unless Additionals.setting?(:issue_autowatch_involved) &&
User.current.pref.autowatch_involved_issue
return if Redmine::Plugin.installed?('redmine_automation') && author_id == RedmineAutomation.bot_user_id
add_autowatcher User.current
add_autowatcher(author) if (new_record? || author_id != author_id_was) && author != User.current
if !assigned_to_id.nil? && assigned_to_id != User.current.id && (new_record? || assigned_to_id != assigned_to_id_was)
add_autowatcher assigned_to
end
true
end
def log_time_allowed?(user = User.current)
!status_was.is_closed || user.allowed_to?(:log_time_on_closed_issues, project)
end
def editable_with_additionals?(user = User.current)
return false unless editable_without_additionals? user
return true unless closed?
return true unless Additionals.setting? :issue_freezed_with_close
user.allowed_to? :edit_closed_issues, project
end
end
def autoassign_get_group_list
return unless Setting.issue_group_assignment?
project.memberships
.active
.where("#{Principal.table_name}.type='Group'")
.includes(:user, :roles)
.each_with_object({}) do |m, h|
m.roles.each do |r|
h[r] ||= []
h[r] << m.principal
end
h
end
end
def new_ticket_message
@new_ticket_message ||= Additionals.setting(:new_ticket_message).presence || ''
end
def status_x_affected?(new_status_id)
return false unless Additionals.setting? :issue_current_user_status
return false if Additionals.setting(:issue_assign_to_x).blank?
Additionals.setting(:issue_assign_to_x).include? new_status_id.to_s
end
private
def auto_assigned_to
return if !Additionals.setting?(:issue_auto_assign) ||
Additionals.setting(:issue_auto_assign_status).blank? ||
Additionals.setting(:issue_auto_assign_role).blank? ||
assigned_to_id.present?
return unless Additionals.setting(:issue_auto_assign_status).include?(status_id.to_s)
self.assigned_to_id = auto_assigned_to_user
true
end
def auto_assigned_to_user
manager_role = Role.builtin.find_by(id: Additionals.setting(:issue_auto_assign_role))
groups = autoassign_get_group_list
return groups[manager_role].first.id unless groups.nil? || groups[manager_role].blank?
users_list = project.users_by_role
return users_list[manager_role].first.id if users_list[manager_role].present?
end
def timelog_required?(check_status_id)
usr = User.current
return false if !Additionals.setting?(:issue_timelog_required) ||
Additionals.setting(:issue_timelog_required_tracker).blank? ||
Additionals.setting(:issue_timelog_required_tracker).exclude?(tracker_id.to_s) ||
Additionals.setting(:issue_timelog_required_status).blank? ||
Additionals.setting(:issue_timelog_required_status).exclude?(check_status_id.to_s) ||
!usr.allowed_to?(:log_time, project) ||
usr.allowed_to?(:issue_timelog_never_required, project) ||
time_entries.present?
true
end
def validate_timelog_required
return true unless timelog_required?(status_id)
errors.add :base, :issue_requires_timelog
end
def validate_change_on_closed
return true if new_record? ||
!status_was.is_closed ||
!changed? ||
!Additionals.setting?(:issue_freezed_with_close) ||
User.current.allowed_to?(:edit_closed_issues, project)
errors.add :base, :issue_changes_not_allowed
end
def validate_current_user_status
if (assigned_to_id_changed? || status_id_changed?) &&
status_x_affected?(status_id) &&
(assigned_to_id.blank? || assigned_to_id != User.current.id)
errors.add :base, :issue_current_user_status
else
true
end
end
def change_status_with_assigned_to_change
return true if !Additionals.setting?(:issue_status_change) ||
Additionals.setting(:issue_status_x).blank? ||
Additionals.setting(:issue_status_y).blank?
if !assigned_to_id_changed? &&
status_id_changed? &&
(Additionals.setting(:issue_status_x).include? status_id_was.to_s) &&
Additionals.setting(:issue_status_y).to_i == status_id
self.assigned_to = author
end
end
end
end
end