@@ -65,12 +65,20 class CustomField < ActiveRecord::Base | |||||
65 | # Returns false, if the custom field can not be used for sorting. |
|
65 | # Returns false, if the custom field can not be used for sorting. | |
66 | def order_statement |
|
66 | def order_statement | |
67 | case field_format |
|
67 | case field_format | |
68 | when 'string', 'list', 'date', 'bool' |
|
68 | when 'string', 'text', 'list', 'date', 'bool' | |
69 | # COALESCE is here to make sure that blank and NULL values are sorted equally |
|
69 | # COALESCE is here to make sure that blank and NULL values are sorted equally | |
70 | "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" + |
|
70 | "COALESCE((SELECT cv_sort.value FROM #{CustomValue.table_name} cv_sort" + | |
71 | " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + |
|
71 | " WHERE cv_sort.customized_type='#{self.class.customized_class.name}'" + | |
72 | " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + |
|
72 | " AND cv_sort.customized_id=#{self.class.customized_class.table_name}.id" + | |
73 | " AND cv_sort.custom_field_id=#{id} LIMIT 1), '')" |
|
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 | else |
|
82 | else | |
75 | nil |
|
83 | nil | |
76 | end |
|
84 | end |
@@ -69,4 +69,16 custom_fields_005: | |||||
69 | is_required: false |
|
69 | is_required: false | |
70 | field_format: float |
|
70 | field_format: float | |
71 | default_value: "" |
|
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 | No newline at end of file |
|
84 |
@@ -8,3 +8,12 custom_fields_trackers_002: | |||||
8 | custom_fields_trackers_003: |
|
8 | custom_fields_trackers_003: | |
9 | custom_field_id: 2 |
|
9 | custom_field_id: 2 | |
10 | tracker_id: 3 |
|
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 | customized_type: Issue |
|
3 | customized_type: Issue | |
4 | custom_field_id: 2 |
|
4 | custom_field_id: 2 | |
5 | customized_id: 3 |
|
5 | customized_id: 3 | |
6 |
id: |
|
6 | id: 6 | |
7 | value: "125" |
|
7 | value: "125" | |
8 | custom_values_007: |
|
8 | custom_values_007: | |
9 | customized_type: Project |
|
9 | customized_type: Project | |
10 | custom_field_id: 3 |
|
10 | custom_field_id: 3 | |
11 | customized_id: 1 |
|
11 | customized_id: 1 | |
12 |
id: |
|
12 | id: 7 | |
13 | value: Stable |
|
13 | value: Stable | |
14 | custom_values_001: |
|
14 | custom_values_001: | |
15 | customized_type: User |
|
15 | customized_type: User | |
16 | custom_field_id: 4 |
|
16 | custom_field_id: 4 | |
17 | customized_id: 3 |
|
17 | customized_id: 3 | |
18 |
id: |
|
18 | id: 1 | |
19 | value: "" |
|
19 | value: "" | |
20 | custom_values_002: |
|
20 | custom_values_002: | |
21 | customized_type: User |
|
21 | customized_type: User | |
22 | custom_field_id: 4 |
|
22 | custom_field_id: 4 | |
23 | customized_id: 4 |
|
23 | customized_id: 4 | |
24 |
id: |
|
24 | id: 2 | |
25 | value: 01 23 45 67 89 |
|
25 | value: 01 23 45 67 89 | |
26 | custom_values_003: |
|
26 | custom_values_003: | |
27 | customized_type: User |
|
27 | customized_type: User | |
28 | custom_field_id: 4 |
|
28 | custom_field_id: 4 | |
29 | customized_id: 2 |
|
29 | customized_id: 2 | |
30 |
id: |
|
30 | id: 3 | |
31 | value: "" |
|
31 | value: "" | |
32 | custom_values_004: |
|
32 | custom_values_004: | |
33 | customized_type: Issue |
|
33 | customized_type: Issue | |
34 | custom_field_id: 2 |
|
34 | custom_field_id: 2 | |
35 | customized_id: 1 |
|
35 | customized_id: 1 | |
36 |
id: |
|
36 | id: 4 | |
37 | value: "125" |
|
37 | value: "125" | |
38 | custom_values_005: |
|
38 | custom_values_005: | |
39 | customized_type: Issue |
|
39 | customized_type: Issue | |
40 | custom_field_id: 2 |
|
40 | custom_field_id: 2 | |
41 | customized_id: 2 |
|
41 | customized_id: 2 | |
42 |
id: |
|
42 | id: 5 | |
43 | value: "" |
|
43 | value: "" | |
44 | custom_values_008: |
|
44 | custom_values_008: | |
45 | customized_type: Issue |
|
45 | customized_type: Issue | |
46 | custom_field_id: 1 |
|
46 | custom_field_id: 1 | |
47 | customized_id: 3 |
|
47 | customized_id: 3 | |
48 |
id: |
|
48 | id: 8 | |
49 | value: "MySQL" |
|
49 | value: "MySQL" | |
50 | custom_values_009: |
|
50 | custom_values_009: | |
51 | customized_type: Issue |
|
51 | customized_type: Issue | |
52 | custom_field_id: 2 |
|
52 | custom_field_id: 2 | |
53 | customized_id: 3 |
|
53 | customized_id: 3 | |
54 |
id: |
|
54 | id: 9 | |
55 | value: "this is a stringforcustomfield search" |
|
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 | No newline at end of file |
|
86 |
@@ -185,6 +185,7 class QueryTest < Test::Unit::TestCase | |||||
185 | :conditions => q.statement, |
|
185 | :conditions => q.statement, | |
186 | :order => "#{c.sortable} ASC" |
|
186 | :order => "#{c.sortable} ASC" | |
187 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
|
187 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | |
|
188 | assert !values.empty? | |||
188 | assert_equal values.sort, values |
|
189 | assert_equal values.sort, values | |
189 | end |
|
190 | end | |
190 |
|
191 | |||
@@ -198,9 +199,24 class QueryTest < Test::Unit::TestCase | |||||
198 | :conditions => q.statement, |
|
199 | :conditions => q.statement, | |
199 | :order => "#{c.sortable} DESC" |
|
200 | :order => "#{c.sortable} DESC" | |
200 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} |
|
201 | values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s} | |
|
202 | assert !values.empty? | |||
201 | assert_equal values.sort.reverse, values |
|
203 | assert_equal values.sort.reverse, values | |
202 | end |
|
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 | def test_label_for |
|
220 | def test_label_for | |
205 | q = Query.new |
|
221 | q = Query.new | |
206 | assert_equal 'assigned_to', q.label_for('assigned_to_id') |
|
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