Initial Redmine tooling and local plugin forks
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
# This file is a part of Redmine CRM (redmine_contacts) plugin,
|
||||
# customer relationship management plugin for Redmine
|
||||
#
|
||||
# Copyright (C) 2010-2018 RedmineUP
|
||||
# http://www.redmineup.com/
|
||||
#
|
||||
# redmine_contacts 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 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# redmine_contacts 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 redmine_contacts. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
module CrmQuery
|
||||
|
||||
def self.included(base)
|
||||
base.send :include, InstanceMethods
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def visible(*args)
|
||||
user = args.shift || User.current
|
||||
base = Project.allowed_to_condition(user, "view_#{queried_class.name.pluralize.downcase}".to_sym, *args)
|
||||
if Redmine::VERSION.to_s < '2.4'
|
||||
user_id = user.logged? ? user.id : 0
|
||||
return includes(:project).where("(#{table_name}.project_id IS NULL OR (#{base})) AND (#{table_name}.is_public = ? OR #{table_name}.user_id = ?)", true, user_id)
|
||||
end
|
||||
|
||||
scope = eager_load(:project).where("#{table_name}.project_id IS NULL OR (#{base})")
|
||||
if user.admin?
|
||||
scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", Query::VISIBILITY_PRIVATE, user.id)
|
||||
elsif user.memberships.any?
|
||||
scope.where("#{table_name}.visibility = ?" +
|
||||
" OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" +
|
||||
"SELECT DISTINCT q.id FROM #{table_name} q" +
|
||||
" INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" +
|
||||
" INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" +
|
||||
" INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" +
|
||||
" WHERE q.project_id IS NULL OR q.project_id = m.project_id))" +
|
||||
" OR #{table_name}.user_id = ?",
|
||||
Query::VISIBILITY_PUBLIC, Query::VISIBILITY_ROLES, user.id, user.id)
|
||||
elsif user.logged?
|
||||
scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", Query::VISIBILITY_PUBLIC, user.id)
|
||||
else
|
||||
scope.where("#{table_name}.visibility = ?", Query::VISIBILITY_PUBLIC)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def visible?(user=User.current)
|
||||
return true if user.admin?
|
||||
return false unless project.nil? || user.allowed_to?("view_#{queried_class.name.pluralize.downcase}".to_sym, project)
|
||||
case visibility
|
||||
when Query::VISIBILITY_PUBLIC
|
||||
true
|
||||
when Query::VISIBILITY_ROLES
|
||||
if project
|
||||
(user.roles_for_project(project) & roles).any?
|
||||
else
|
||||
Member.where(:user_id => user.id).joins(:roles).where(:member_roles => {:role_id => roles.map(&:id)}).any?
|
||||
end
|
||||
else
|
||||
user == self.user
|
||||
end
|
||||
end
|
||||
|
||||
def is_private?
|
||||
visibility == Query::VISIBILITY_PRIVATE
|
||||
end
|
||||
|
||||
def is_public?
|
||||
!is_private?
|
||||
end
|
||||
|
||||
def initialize_project_filter(position=nil)
|
||||
if project.blank?
|
||||
project_values = []
|
||||
if User.current.logged? && User.current.memberships.any?
|
||||
project_values << ["<< #{l(:label_my_projects).downcase} >>", "mine"]
|
||||
end
|
||||
project_values += all_projects_values
|
||||
add_available_filter("project_id", :order => position,
|
||||
:type => :list, :values => project_values
|
||||
) unless project_values.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_author_filter(position=nil)
|
||||
add_available_filter("author_id", :order => position,
|
||||
:type => :list_optional, :values => users_values
|
||||
) unless users_values.empty?
|
||||
end
|
||||
|
||||
def initialize_assignee_filter(position=nil)
|
||||
add_available_filter("assigned_to_id", :order => position,
|
||||
:type => :list_optional, :values => users_values
|
||||
) unless users_values.empty?
|
||||
end
|
||||
|
||||
def initialize_contact_country_filter(position=nil)
|
||||
contact_countries = l(:label_crm_countries).map{|k, v| [v, k]}
|
||||
add_available_filter("contact_country", :order => position,
|
||||
:type => :list_optional, :values => contact_countries, :label => :label_crm_contact_country
|
||||
) unless contact_countries.empty?
|
||||
end
|
||||
|
||||
def initialize_contact_city_filter(position=nil)
|
||||
add_available_filter("contact_city", :order => position,
|
||||
:type => :string, :label => :label_crm_contact_city
|
||||
)
|
||||
end
|
||||
|
||||
def sql_for_contact_country_field(field, operator, value)
|
||||
if operator == '*' # Any group
|
||||
contact_countries = l(:label_crm_countries).map{|k, v| k.to_s}
|
||||
operator = '=' # Override the operator since we want to find by assigned_to
|
||||
elsif operator == "!*"
|
||||
contact_countries = l(:label_crm_countries).map{|k, v| k.to_s}
|
||||
operator = '!' # Override the operator since we want to find by assigned_to
|
||||
else
|
||||
contact_countries = value
|
||||
end
|
||||
'(' + sql_for_field("address_id", operator, contact_countries, Address.table_name, "country_code", false) + ')'
|
||||
end
|
||||
|
||||
def sql_for_contact_city_field(field, operator, value)
|
||||
sql_for_field(field, operator, value, Address.table_name, "city")
|
||||
end
|
||||
|
||||
def sql_for_ids_field(field, operator, value)
|
||||
if operator == "*"
|
||||
"1=1"
|
||||
elsif operator == "="
|
||||
ids = value.first.to_s.scan(/\d+/).map(&:to_i).join(",")
|
||||
if ids.present?
|
||||
"#{self.queried_class.table_name}.id IN (#{ids})"
|
||||
else
|
||||
"1=0"
|
||||
end
|
||||
elsif operator == ">="
|
||||
id = value.first.to_s.scan(/\d+/).map(&:to_i).first
|
||||
if id.present?
|
||||
"#{self.queried_class.table_name}.id >= (#{id})"
|
||||
else
|
||||
"1=0"
|
||||
end
|
||||
elsif operator == "<="
|
||||
id = value.first.to_s.scan(/\d+/).map(&:to_i).first
|
||||
if id.present?
|
||||
"#{self.queried_class.table_name}.id <= (#{id})"
|
||||
else
|
||||
"1=0"
|
||||
end
|
||||
elsif operator == "><"
|
||||
if value.is_a? Array
|
||||
"#{self.queried_class.table_name}.id BETWEEN #{value.first} AND #{value.last}"
|
||||
else
|
||||
"1=0"
|
||||
end
|
||||
else
|
||||
"1=0"
|
||||
end
|
||||
end if Redmine::VERSION.to_s >= '3.3'
|
||||
|
||||
|
||||
def principals
|
||||
return @principals if @principals
|
||||
@principals = []
|
||||
if project
|
||||
@principals += project.principals.sort
|
||||
unless project.leaf?
|
||||
subprojects = project.descendants.visible.all
|
||||
@principals += Principal.member_of(subprojects)
|
||||
end
|
||||
else
|
||||
if all_projects.any?
|
||||
@principals += Principal.member_of(all_projects)
|
||||
end
|
||||
end
|
||||
@principals.uniq!
|
||||
@principals.sort!
|
||||
end
|
||||
|
||||
def users_values
|
||||
return @users_values if @users_values
|
||||
users = principals.select {|p| p.is_a?(User)}
|
||||
@users_values = []
|
||||
@users_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
|
||||
@users_values += users.collect{|s| [s.name, s.id.to_s] }
|
||||
@users_values
|
||||
end
|
||||
|
||||
def object_count
|
||||
objects_scope.count
|
||||
rescue ::ActiveRecord::StatementInvalid => e
|
||||
raise StatementInvalid.new(e.message)
|
||||
end
|
||||
|
||||
def object_count_by_group
|
||||
r = nil
|
||||
if grouped?
|
||||
begin
|
||||
# Rails3 will raise an (unexpected) RecordNotFound if there's only a nil group value
|
||||
r = objects_scope.
|
||||
joins(joins_for_order_statement(group_by_statement)).
|
||||
group(group_by_statement).count
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
r = {nil => object_count}
|
||||
end
|
||||
c = group_by_column
|
||||
if c.is_a?(QueryCustomFieldColumn)
|
||||
r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
|
||||
end
|
||||
end
|
||||
r
|
||||
rescue ::ActiveRecord::StatementInvalid => e
|
||||
raise StatementInvalid.new(e.message)
|
||||
end
|
||||
|
||||
def objects_scope(options={})
|
||||
raise NotImplementedError.new("You must implement #{name}.")
|
||||
end
|
||||
|
||||
def results_scope(options={})
|
||||
order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
|
||||
|
||||
objects_scope(options).
|
||||
order(order_option).
|
||||
joins(joins_for_order_statement(order_option.join(','))).
|
||||
limit(options[:limit]).
|
||||
offset(options[:offset])
|
||||
rescue ::ActiveRecord::StatementInvalid => e
|
||||
raise StatementInvalid.new(e.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user