mirror of
https://github.com/redmine/redmine.git
synced 2026-01-19 14:03:06 +01:00
Merged r14944 (#21413).
git-svn-id: http://svn.redmine.org/redmine/branches/3.2-stable@14945 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -153,6 +153,10 @@ class CustomField < ActiveRecord::Base
|
||||
format.query_filter_options(self, query)
|
||||
end
|
||||
|
||||
def totalable?
|
||||
format.totalable_supported
|
||||
end
|
||||
|
||||
# Returns a ORDER BY clause that can used to sort customized
|
||||
# objects by their value of the custom field.
|
||||
# Returns nil if the custom field can not be used for sorting.
|
||||
|
||||
@@ -80,7 +80,7 @@ class QueryCustomFieldColumn < QueryColumn
|
||||
self.name = "cf_#{custom_field.id}".to_sym
|
||||
self.sortable = custom_field.order_statement || false
|
||||
self.groupable = custom_field.group_statement || false
|
||||
self.totalable = ['int', 'float'].include?(custom_field.field_format)
|
||||
self.totalable = custom_field.totalable?
|
||||
@inline = true
|
||||
@cf = custom_field
|
||||
end
|
||||
@@ -692,7 +692,7 @@ class Query < ActiveRecord::Base
|
||||
end
|
||||
if column.is_a?(QueryCustomFieldColumn)
|
||||
custom_field = column.custom_field
|
||||
send "total_for_#{custom_field.field_format}_custom_field", custom_field, scope
|
||||
send "total_for_custom_field", custom_field, scope
|
||||
else
|
||||
send "total_for_#{column.name}", scope
|
||||
end
|
||||
@@ -710,21 +710,9 @@ class Query < ActiveRecord::Base
|
||||
group(group_by_statement)
|
||||
end
|
||||
|
||||
def total_for_float_custom_field(custom_field, scope)
|
||||
total_for_custom_field(custom_field, scope) {|t| t.to_f.round(2)}
|
||||
end
|
||||
|
||||
def total_for_int_custom_field(custom_field, scope)
|
||||
total_for_custom_field(custom_field, scope) {|t| t.to_i}
|
||||
end
|
||||
|
||||
def total_for_custom_field(custom_field, scope, &block)
|
||||
total = scope.joins(:custom_values).
|
||||
where(:custom_values => {:custom_field_id => custom_field.id}).
|
||||
where.not(:custom_values => {:value => ''}).
|
||||
sum("CAST(#{CustomValue.table_name}.value AS decimal(30,3))")
|
||||
|
||||
total = map_total(total, &block) if block_given?
|
||||
total = custom_field.format.total_for_scope(custom_field, scope)
|
||||
total = map_total(total) {|t| custom_field.format.cast_total_value(custom_field, t)}
|
||||
total
|
||||
end
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ module Redmine
|
||||
class_attribute :searchable_supported
|
||||
self.searchable_supported = false
|
||||
|
||||
# Set this to true if field values can be summed up
|
||||
class_attribute :totalable_supported
|
||||
self.totalable_supported = false
|
||||
|
||||
# Restricts the classes that the custom field can be added to
|
||||
# Set to nil for no restrictions
|
||||
class_attribute :customized_class_names
|
||||
@@ -370,6 +374,7 @@ module Redmine
|
||||
|
||||
class Numeric < Unbounded
|
||||
self.form_partial = 'custom_fields/formats/numeric'
|
||||
self.totalable_supported = true
|
||||
|
||||
def order_statement(custom_field)
|
||||
# Make the database cast values into numeric
|
||||
@@ -377,6 +382,18 @@ module Redmine
|
||||
# CustomValue validations should ensure that it doesn't occur
|
||||
"CAST(CASE #{join_alias custom_field}.value WHEN '' THEN '0' ELSE #{join_alias custom_field}.value END AS decimal(30,3))"
|
||||
end
|
||||
|
||||
# Returns totals for the given scope
|
||||
def total_for_scope(custom_field, scope)
|
||||
scope.joins(:custom_values).
|
||||
where(:custom_values => {:custom_field_id => custom_field.id}).
|
||||
where.not(:custom_values => {:value => ''}).
|
||||
sum("CAST(#{CustomValue.table_name}.value AS decimal(30,3))")
|
||||
end
|
||||
|
||||
def cast_total_value(custom_field, value)
|
||||
cast_single_value(custom_field, value)
|
||||
end
|
||||
end
|
||||
|
||||
class IntFormat < Numeric
|
||||
@@ -412,6 +429,10 @@ module Redmine
|
||||
value.to_f
|
||||
end
|
||||
|
||||
def cast_total_value(custom_field, value)
|
||||
value.to_f.round(2)
|
||||
end
|
||||
|
||||
def validate_single_value(custom_field, value, customized=nil)
|
||||
errs = super
|
||||
errs << ::I18n.t('activerecord.errors.messages.invalid') unless (Kernel.Float(value) rescue nil)
|
||||
|
||||
Reference in New Issue
Block a user