@@ -65,12 +65,20 class CustomField < ActiveRecord::Base | |||
|
65 | 65 | # Returns false, if the custom field can not be used for sorting. |
|
66 | 66 | def order_statement |
|
67 | 67 | case field_format |
|
68 | when 'string', 'list', 'date', 'bool' | |
|
68 | when 'string', 'text', 'list', 'date', 'bool' | |
|
69 | 69 | # COALESCE is here to make sure that blank and NULL values are sorted equally |
|
70 | 70 | "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" + |
|
71 | 71 | " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + |
|
72 | 72 | " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + |
|
73 | 73 | " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')" |
|
74 | when 'int', 'float' | |
|
75 | # Make the database cast values into numeric | |
|
76 | # Postgresql will raise an error if a value can not be casted! | |
|
77 | # CustomValue validations should ensure that it doesn't occur | |
|
78 | "(SELECT CAST(cv_sort.value AS decimal(60,3)) FROM #{CustomValue.table_name} cv_sort" + | |
|
79 | " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |
|
80 | " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |
|
81 | " AND cv_sort.custom_field_id=#{id} AND cv_sort.value <> '' AND cv_sort.value IS NOT NULL LIMIT 1)" | |
|
74 | 82 | else |
|
75 | 83 | nil |
|
76 | 84 | end |
@@ -69,4 +69,16 custom_fields_005: | |||
|
69 | 69 | is_required: false |
|
70 | 70 | field_format: float |
|
71 | 71 | default_value: "" |
|
72 | custom_fields_006: | |
|
73 | name: Float field | |
|
74 | min_length: 0 | |
|
75 | regexp: "" | |
|
76 | is_for_all: true | |
|
77 | type: IssueCustomField | |
|
78 | max_length: 0 | |
|
79 | possible_values: "" | |
|
80 | id: 6 | |
|
81 | is_required: false | |
|
82 | field_format: float | |
|
83 | default_value: "" | |
|
72 | 84 | No newline at end of file |
@@ -8,3 +8,12 custom_fields_trackers_002: | |||
|
8 | 8 | custom_fields_trackers_003: |
|
9 | 9 | custom_field_id: 2 |
|
10 | 10 | tracker_id: 3 |
|
11 | custom_fields_trackers_004: | |
|
12 | custom_field_id: 6 | |
|
13 | tracker_id: 1 | |
|
14 | custom_fields_trackers_005: | |
|
15 | custom_field_id: 6 | |
|
16 | tracker_id: 2 | |
|
17 | custom_fields_trackers_006: | |
|
18 | custom_field_id: 6 | |
|
19 | tracker_id: 3 |
@@ -3,54 +3,84 custom_values_006: | |||
|
3 | 3 | customized_type: Issue |
|
4 | 4 | custom_field_id: 2 |
|
5 | 5 | customized_id: 3 |
|
6 |
id: |
|
|
6 | id: 6 | |
|
7 | 7 | value: "125" |
|
8 | 8 | custom_values_007: |
|
9 | 9 | customized_type: Project |
|
10 | 10 | custom_field_id: 3 |
|
11 | 11 | customized_id: 1 |
|
12 |
id: |
|
|
12 | id: 7 | |
|
13 | 13 | value: Stable |
|
14 | 14 | custom_values_001: |
|
15 | 15 | customized_type: User |
|
16 | 16 | custom_field_id: 4 |
|
17 | 17 | customized_id: 3 |
|
18 |
id: |
|
|
18 | id: 1 | |
|
19 | 19 | value: "" |
|
20 | 20 | custom_values_002: |
|
21 | 21 | customized_type: User |
|
22 | 22 | custom_field_id: 4 |
|
23 | 23 | customized_id: 4 |
|
24 |
id: |
|
|
24 | id: 2 | |
|
25 | 25 | value: 01 23 45 67 89 |
|
26 | 26 | custom_values_003: |
|
27 | 27 | customized_type: User |
|
28 | 28 | custom_field_id: 4 |
|
29 | 29 | customized_id: 2 |
|
30 |
id: |
|
|
30 | id: 3 | |
|
31 | 31 | value: "" |
|
32 | 32 | custom_values_004: |
|
33 | 33 | customized_type: Issue |
|
34 | 34 | custom_field_id: 2 |
|
35 | 35 | customized_id: 1 |
|
36 |
id: |
|
|
36 | id: 4 | |
|
37 | 37 | value: "125" |
|
38 | 38 | custom_values_005: |
|
39 | 39 | customized_type: Issue |
|
40 | 40 | custom_field_id: 2 |
|
41 | 41 | customized_id: 2 |
|
42 |
id: |
|
|
42 | id: 5 | |
|
43 | 43 | value: "" |
|
44 | 44 | custom_values_008: |
|
45 | 45 | customized_type: Issue |
|
46 | 46 | custom_field_id: 1 |
|
47 | 47 | customized_id: 3 |
|
48 |
id: |
|
|
48 | id: 8 | |
|
49 | 49 | value: "MySQL" |
|
50 | 50 | custom_values_009: |
|
51 | 51 | customized_type: Issue |
|
52 | 52 | custom_field_id: 2 |
|
53 | 53 | customized_id: 3 |
|
54 |
id: |
|
|
54 | id: 9 | |
|
55 | 55 | value: "this is a stringforcustomfield search" |
|
56 | custom_values_010: | |
|
57 | customized_type: Issue | |
|
58 | custom_field_id: 6 | |
|
59 | customized_id: 1 | |
|
60 | id: 10 | |
|
61 | value: "2.1" | |
|
62 | custom_values_011: | |
|
63 | customized_type: Issue | |
|
64 | custom_field_id: 6 | |
|
65 | customized_id: 2 | |
|
66 | id: 11 | |
|
67 | value: "2.05" | |
|
68 | custom_values_012: | |
|
69 | customized_type: Issue | |
|
70 | custom_field_id: 6 | |
|
71 | customized_id: 3 | |
|
72 | id: 12 | |
|
73 | value: "11.65" | |
|
74 | custom_values_013: | |
|
75 | customized_type: Issue | |
|
76 | custom_field_id: 6 | |
|
77 | customized_id: 7 | |
|
78 | id: 13 | |
|
79 | value: "" | |
|
80 | custom_values_014: | |
|
81 | customized_type: Issue | |
|
82 | custom_field_id: 6 | |
|
83 | customized_id: 5 | |
|
84 | id: 14 | |
|
85 | value: "-7.6" | |
|
56 | 86 | No newline at end of file |
@@ -185,6 +185,7 class QueryTest < Test::Unit::TestCase | |||
|
185 | 185 | :conditions => q.statement, |
|
186 | 186 | :order => "#{c.sortable} ASC" |
|
187 | 187 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
|
188 | assert !values.empty? | |
|
188 | 189 | assert_equal values.sort, values |
|
189 | 190 | end |
|
190 | 191 | |
@@ -198,9 +199,24 class QueryTest < Test::Unit::TestCase | |||
|
198 | 199 | :conditions => q.statement, |
|
199 | 200 | :order => "#{c.sortable} DESC" |
|
200 | 201 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
|
202 | assert !values.empty? | |
|
201 | 203 | assert_equal values.sort.reverse, values |
|
202 | 204 | end |
|
203 | 205 | |
|
206 | def test_sort_by_float_custom_field_asc | |
|
207 | q = Query.new | |
|
208 | c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' } | |
|
209 | assert c | |
|
210 | assert c.sortable | |
|
211 | issues = Issue.find :all, | |
|
212 | :include => [ :assigned_to, :status, :tracker, :project, :priority ], | |
|
213 | :conditions => q.statement, | |
|
214 | :order => "#{c.sortable} ASC" | |
|
215 | values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact | |
|
216 | assert !values.empty? | |
|
217 | assert_equal values.sort, values | |
|
218 | end | |
|
219 | ||
|
204 | 220 | def test_label_for |
|
205 | 221 | q = Query.new |
|
206 | 222 | assert_equal 'assigned_to', q.label_for('assigned_to_id') |
General Comments 0
You need to be logged in to leave comments.
Login now