Revision 12380
Added by Jean-Philippe Lang over 11 years ago
sandbox/custom_fields/app/models/custom_field.rb | ||
---|---|---|
159 | 159 |
# Returns nil if the custom field can not be used for sorting. |
160 | 160 |
def order_statement |
161 | 161 |
return nil if multiple? |
162 |
case field_format |
|
163 |
when 'string', 'text', 'list', 'date', 'bool' |
|
164 |
# COALESCE is here to make sure that blank and NULL values are sorted equally |
|
165 |
"COALESCE(#{join_alias}.value, '')" |
|
166 |
when 'int', 'float' |
|
167 |
# Make the database cast values into numeric |
|
168 |
# Postgresql will raise an error if a value can not be casted! |
|
169 |
# CustomValue validations should ensure that it doesn't occur |
|
170 |
"CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,3))" |
|
171 |
when 'user', 'version' |
|
172 |
value_class.fields_for_order_statement(value_join_alias) |
|
173 |
else |
|
174 |
nil |
|
175 |
end |
|
162 |
format.order_statement(self) |
|
176 | 163 |
end |
177 | 164 |
|
178 | 165 |
# Returns a GROUP BY clause that can used to group by custom value |
179 | 166 |
# Returns nil if the custom field can not be used for grouping. |
180 | 167 |
def group_statement |
181 | 168 |
return nil if multiple? |
182 |
case field_format |
|
183 |
when 'list', 'date', 'bool', 'int' |
|
184 |
order_statement |
|
185 |
when 'user', 'version' |
|
186 |
"COALESCE(#{join_alias}.value, '')" |
|
187 |
else |
|
188 |
nil |
|
189 |
end |
|
169 |
format.group_statement(self) |
|
190 | 170 |
end |
191 | 171 |
|
192 | 172 |
def join_for_order_statement |
193 |
case field_format |
|
194 |
when 'user', 'version' |
|
195 |
"LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" + |
|
196 |
" ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" + |
|
197 |
" AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" + |
|
198 |
" AND #{join_alias}.custom_field_id = #{id}" + |
|
199 |
" AND (#{visibility_by_project_condition})" + |
|
200 |
" AND #{join_alias}.value <> ''" + |
|
201 |
" AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" + |
|
202 |
" WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" + |
|
203 |
" AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" + |
|
204 |
" AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)" + |
|
205 |
" LEFT OUTER JOIN #{value_class.table_name} #{value_join_alias}" + |
|
206 |
" ON CAST(CASE #{join_alias}.value WHEN '' THEN '0' ELSE #{join_alias}.value END AS decimal(30,0)) = #{value_join_alias}.id" |
|
207 |
when 'int', 'float' |
|
208 |
"LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" + |
|
209 |
" ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" + |
|
210 |
" AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" + |
|
211 |
" AND #{join_alias}.custom_field_id = #{id}" + |
|
212 |
" AND (#{visibility_by_project_condition})" + |
|
213 |
" AND #{join_alias}.value <> ''" + |
|
214 |
" AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" + |
|
215 |
" WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" + |
|
216 |
" AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" + |
|
217 |
" AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)" |
|
218 |
when 'string', 'text', 'list', 'date', 'bool' |
|
219 |
"LEFT OUTER JOIN #{CustomValue.table_name} #{join_alias}" + |
|
220 |
" ON #{join_alias}.customized_type = '#{self.class.customized_class.base_class.name}'" + |
|
221 |
" AND #{join_alias}.customized_id = #{self.class.customized_class.table_name}.id" + |
|
222 |
" AND #{join_alias}.custom_field_id = #{id}" + |
|
223 |
" AND (#{visibility_by_project_condition})" + |
|
224 |
" AND #{join_alias}.id = (SELECT max(#{join_alias}_2.id) FROM #{CustomValue.table_name} #{join_alias}_2" + |
|
225 |
" WHERE #{join_alias}_2.customized_type = #{join_alias}.customized_type" + |
|
226 |
" AND #{join_alias}_2.customized_id = #{join_alias}.customized_id" + |
|
227 |
" AND #{join_alias}_2.custom_field_id = #{join_alias}.custom_field_id)" |
|
228 |
else |
|
229 |
nil |
|
230 |
end |
|
173 |
format.join_for_order_statement(self) |
|
231 | 174 |
end |
232 | 175 |
|
233 |
def join_alias |
|
234 |
"cf_#{id}" |
|
235 |
end |
|
236 |
|
|
237 |
def value_join_alias |
|
238 |
join_alias + "_" + field_format |
|
239 |
end |
|
240 |
|
|
241 | 176 |
def visibility_by_project_condition(project_key=nil, user=User.current) |
242 | 177 |
if visible? || user.admin? |
243 | 178 |
"1=1" |
sandbox/custom_fields/lib/redmine/field_format.rb | ||
---|---|---|
175 | 175 |
|
176 | 176 |
def before_custom_field_save(custom_field) |
177 | 177 |
end |
178 |
|
|
179 |
# Returns a ORDER BY clause that can used to sort customized |
|
180 |
# objects by their value of the custom field. |
|
181 |
# Returns nil if the custom field can not be used for sorting. |
|
182 |
def order_statement(custom_field) |
|
183 |
# COALESCE is here to make sure that blank and NULL values are sorted equally |
|
184 |
"COALESCE(#{join_alias custom_field}.value, '')" |
|
185 |
end |
|
186 |
|
|
187 |
# Returns a GROUP BY clause that can used to group by custom value |
|
188 |
# Returns nil if the custom field can not be used for grouping. |
|
189 |
def group_statement(custom_field) |
|
190 |
nil |
|
191 |
end |
|
192 |
|
|
193 |
# Returns a JOIN clause that is added to the query when sorting by custom values |
|
194 |
def join_for_order_statement(custom_field) |
|
195 |
alias_name = join_alias(custom_field) |
|
196 |
|
|
197 |
"LEFT OUTER JOIN #{CustomValue.table_name} #{alias_name}" + |
|
198 |
" ON #{alias_name}.customized_type = '#{custom_field.class.customized_class.base_class.name}'" + |
|
199 |
" AND #{alias_name}.customized_id = #{custom_field.class.customized_class.table_name}.id" + |
|
200 |
" AND #{alias_name}.custom_field_id = #{custom_field.id}" + |
|
201 |
" AND (#{custom_field.visibility_by_project_condition})" + |
|
202 |
" AND #{alias_name}.value <> ''" + |
|
203 |
" AND #{alias_name}.id = (SELECT max(#{alias_name}_2.id) FROM #{CustomValue.table_name} #{alias_name}_2" + |
|
204 |
" WHERE #{alias_name}_2.customized_type = #{alias_name}.customized_type" + |
|
205 |
" AND #{alias_name}_2.customized_id = #{alias_name}.customized_id" + |
|
206 |
" AND #{alias_name}_2.custom_field_id = #{alias_name}.custom_field_id)" |
|
207 |
end |
|
208 |
|
|
209 |
def join_alias(custom_field) |
|
210 |
"cf_#{custom_field.id}" |
|
211 |
end |
|
212 |
protected :join_alias |
|
178 | 213 |
end |
179 | 214 |
|
180 | 215 |
class Unbounded < Base |
... | ... | |
278 | 313 |
|
279 | 314 |
class Numeric < Unbounded |
280 | 315 |
self.form_partial = 'custom_fields/formats/numeric' |
316 |
|
|
317 |
def order_statement(custom_field) |
|
318 |
# Make the database cast values into numeric |
|
319 |
# Postgresql will raise an error if a value can not be casted! |
|
320 |
# CustomValue validations should ensure that it doesn't occur |
|
321 |
"CAST(CASE #{join_alias custom_field}.value WHEN '' THEN '0' ELSE #{join_alias custom_field}.value END AS decimal(30,3))" |
|
322 |
end |
|
281 | 323 |
end |
282 | 324 |
|
283 | 325 |
class IntFormat < Numeric |
... | ... | |
300 | 342 |
def query_filter_options(custom_field, query) |
301 | 343 |
{:type => :integer} |
302 | 344 |
end |
345 |
|
|
346 |
def group_statement(custom_field) |
|
347 |
order_statement(custom_field) |
|
348 |
end |
|
303 | 349 |
end |
304 | 350 |
|
305 | 351 |
class FloatFormat < Numeric |
... | ... | |
350 | 396 |
def query_filter_options(custom_field, query) |
351 | 397 |
{:type => :date} |
352 | 398 |
end |
399 |
|
|
400 |
def group_statement(custom_field) |
|
401 |
order_statement(custom_field) |
|
402 |
end |
|
353 | 403 |
end |
354 | 404 |
|
355 | 405 |
class BoolFormat < Base |
... | ... | |
385 | 435 |
def query_filter_options(custom_field, query) |
386 | 436 |
{:type => :list, :values => possible_values_options(custom_field)} |
387 | 437 |
end |
438 |
|
|
439 |
def group_statement(custom_field) |
|
440 |
order_statement(custom_field) |
|
441 |
end |
|
388 | 442 |
end |
389 | 443 |
|
390 | 444 |
class List < Base |
... | ... | |
451 | 505 |
[] |
452 | 506 |
end |
453 | 507 |
end |
508 |
|
|
509 |
def group_statement(custom_field) |
|
510 |
order_statement(custom_field) |
|
511 |
end |
|
454 | 512 |
end |
455 | 513 |
|
456 | 514 |
class RecordList < List |
... | ... | |
473 | 531 |
end |
474 | 532 |
options |
475 | 533 |
end |
534 |
|
|
535 |
def order_statement(custom_field) |
|
536 |
if target_class.respond_to?(:fields_for_order_statement) |
|
537 |
target_class.fields_for_order_statement(value_join_alias(custom_field)) |
|
538 |
end |
|
539 |
end |
|
540 |
|
|
541 |
def group_statement(custom_field) |
|
542 |
"COALESCE(#{join_alias custom_field}.value, '')" |
|
543 |
end |
|
544 |
|
|
545 |
def join_for_order_statement(custom_field) |
|
546 |
alias_name = join_alias(custom_field) |
|
547 |
|
|
548 |
"LEFT OUTER JOIN #{CustomValue.table_name} #{alias_name}" + |
|
549 |
" ON #{alias_name}.customized_type = '#{custom_field.class.customized_class.base_class.name}'" + |
|
550 |
" AND #{alias_name}.customized_id = #{custom_field.class.customized_class.table_name}.id" + |
|
551 |
" AND #{alias_name}.custom_field_id = #{custom_field.id}" + |
|
552 |
" AND (#{custom_field.visibility_by_project_condition})" + |
|
553 |
" AND #{alias_name}.value <> ''" + |
|
554 |
" AND #{alias_name}.id = (SELECT max(#{alias_name}_2.id) FROM #{CustomValue.table_name} #{alias_name}_2" + |
|
555 |
" WHERE #{alias_name}_2.customized_type = #{alias_name}.customized_type" + |
|
556 |
" AND #{alias_name}_2.customized_id = #{alias_name}.customized_id" + |
|
557 |
" AND #{alias_name}_2.custom_field_id = #{alias_name}.custom_field_id)" + |
|
558 |
" LEFT OUTER JOIN #{target_class.table_name} #{value_join_alias custom_field}" + |
|
559 |
" ON CAST(CASE #{alias_name}.value WHEN '' THEN '0' ELSE #{alias_name}.value END AS decimal(30,0)) = #{value_join_alias custom_field}.id" |
|
560 |
end |
|
561 |
|
|
562 |
def value_join_alias(custom_field) |
|
563 |
join_alias(custom_field) + "_" + custom_field.field_format |
|
564 |
end |
|
565 |
protected :value_join_alias |
|
476 | 566 |
end |
477 | 567 |
|
478 | 568 |
class UserFormat < RecordList |
sandbox/custom_fields/lib/redmine/helpers/time_report.rb | ||
---|---|---|
138 | 138 |
|
139 | 139 |
# Add list and boolean custom fields as available criteria |
140 | 140 |
custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf| |
141 |
@available_criteria["cf_#{cf.id}"] = {:sql => "#{cf.join_alias}.value",
|
|
141 |
@available_criteria["cf_#{cf.id}"] = {:sql => cf.group_statement,
|
|
142 | 142 |
:joins => cf.join_for_order_statement, |
143 | 143 |
:format => cf.field_format, |
144 | 144 |
:custom_field => cf, |
Also available in: Unified diff
Move format specific statements to Redmine::FieldFormat.