kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.6 KiB
128 lines
3.6 KiB
#-- encoding: UTF-8
|
|
|
|
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) 2012-2021 the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# 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.
|
|
#
|
|
# See docs/COPYRIGHT.rdoc for more details.
|
|
#++
|
|
|
|
module ::Query::Results::Sums
|
|
include ActionView::Helpers::NumberHelper
|
|
|
|
def all_total_sums
|
|
group_sums = sums_select
|
|
|
|
query.summed_up_columns.inject({}) do |result, column|
|
|
value = group_sums.first
|
|
result[column] = value[column.name.to_s] unless value.nil?
|
|
result
|
|
end
|
|
end
|
|
|
|
def all_group_sums
|
|
return nil unless query.grouped?
|
|
|
|
sums_by_id = sums_select(true).inject({}) do |result, group_sum|
|
|
result[group_sum['id']] = {}
|
|
|
|
query.summed_up_columns.each do |column|
|
|
result[group_sum['id']][column] = group_sum[column.name.to_s]
|
|
end
|
|
|
|
result
|
|
end
|
|
|
|
transform_group_keys(sums_by_id)
|
|
end
|
|
|
|
private
|
|
|
|
def sums_select(grouped = false)
|
|
select = if grouped
|
|
["work_packages.id"]
|
|
else
|
|
[]
|
|
end
|
|
|
|
select += query.summed_up_columns.map(&:summable_select)
|
|
|
|
sql = <<~SQL
|
|
SELECT #{select.join(', ')}
|
|
FROM (#{sums_work_package_scope(grouped).to_sql}) work_packages
|
|
#{sums_callable_joins(grouped)}
|
|
SQL
|
|
|
|
connection = ActiveRecord::Base.connection
|
|
|
|
connection.uncached do
|
|
connection.select_all(sql)
|
|
end
|
|
end
|
|
|
|
def sums_work_package_scope(grouped)
|
|
scope = WorkPackage
|
|
.where(id: work_packages)
|
|
.except(:order, :select)
|
|
.select(sums_work_package_scope_selects(grouped))
|
|
|
|
if grouped
|
|
scope.group(query.group_by_statement)
|
|
else
|
|
scope
|
|
end
|
|
end
|
|
|
|
def sums_callable_joins(grouped)
|
|
callable_summed_up_columns
|
|
.map do |c|
|
|
join_condition = if grouped
|
|
"#{c.name}.id = work_packages.id OR #{c.name}.id IS NULL AND work_packages.id IS NULL"
|
|
else
|
|
"TRUE"
|
|
end
|
|
|
|
"LEFT OUTER JOIN (#{c.summable.(query, grouped).to_sql}) #{c.name} ON #{join_condition}"
|
|
end
|
|
.join(' ')
|
|
end
|
|
|
|
def sums_work_package_scope_selects(grouped)
|
|
select = if grouped
|
|
["#{query.group_by_statement} id"]
|
|
else
|
|
[]
|
|
end
|
|
|
|
select + query.summed_up_columns.map(&:summable_work_packages_select).compact.map { |c| "SUM(#{c}) #{c}" }
|
|
end
|
|
|
|
def callable_summed_up_columns
|
|
query.summed_up_columns.select { |column| column.summable.respond_to?(:call) }
|
|
end
|
|
|
|
def non_callable_summed_up_columns
|
|
query.summed_up_columns.map { |column| column.summable.respond_to?(:call) }
|
|
end
|
|
end
|
|
|