Fixed that sorting time entries by custom field raises a SQL error (#14366).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@12042 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
dc5e5eca6b
commit
21fc903c04
|
@ -43,10 +43,10 @@ class TimelogController < ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
||||||
scope = time_entry_scope
|
|
||||||
|
|
||||||
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
|
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
|
||||||
sort_update(@query.sortable_columns)
|
sort_update(@query.sortable_columns)
|
||||||
|
scope = time_entry_scope(:order => sort_clause)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html {
|
||||||
|
@ -55,7 +55,6 @@ class TimelogController < ApplicationController
|
||||||
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
|
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
|
||||||
@entries = scope.all(
|
@entries = scope.all(
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||||
:order => sort_clause,
|
|
||||||
:limit => @entry_pages.per_page,
|
:limit => @entry_pages.per_page,
|
||||||
:offset => @entry_pages.offset
|
:offset => @entry_pages.offset
|
||||||
)
|
)
|
||||||
|
@ -68,15 +67,13 @@ class TimelogController < ApplicationController
|
||||||
@offset, @limit = api_offset_and_limit
|
@offset, @limit = api_offset_and_limit
|
||||||
@entries = scope.all(
|
@entries = scope.all(
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||||
:order => sort_clause,
|
|
||||||
:limit => @limit,
|
:limit => @limit,
|
||||||
:offset => @offset
|
:offset => @offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
format.atom {
|
format.atom {
|
||||||
entries = scope.all(
|
entries = scope.reorder("#{TimeEntry.table_name}.created_on DESC").all(
|
||||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||||
:order => "#{TimeEntry.table_name}.created_on DESC",
|
|
||||||
:limit => Setting.feeds_limit.to_i
|
:limit => Setting.feeds_limit.to_i
|
||||||
)
|
)
|
||||||
render_feed(entries, :title => l(:label_spent_time))
|
render_feed(entries, :title => l(:label_spent_time))
|
||||||
|
@ -84,8 +81,7 @@ class TimelogController < ApplicationController
|
||||||
format.csv {
|
format.csv {
|
||||||
# Export all entries
|
# Export all entries
|
||||||
@entries = scope.all(
|
@entries = scope.all(
|
||||||
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}]
|
||||||
:order => sort_clause
|
|
||||||
)
|
)
|
||||||
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
||||||
}
|
}
|
||||||
|
@ -296,8 +292,8 @@ private
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the TimeEntry scope for index and report actions
|
# Returns the TimeEntry scope for index and report actions
|
||||||
def time_entry_scope
|
def time_entry_scope(options={})
|
||||||
scope = TimeEntry.visible.where(@query.statement)
|
scope = @query.results_scope(options)
|
||||||
if @issue
|
if @issue
|
||||||
scope = scope.on_issue(@issue)
|
scope = scope.on_issue(@issue)
|
||||||
elsif @project
|
elsif @project
|
||||||
|
|
|
@ -100,6 +100,15 @@ class TimeEntryQuery < Query
|
||||||
@default_columns_names ||= [:project, :spent_on, :user, :activity, :issue, :comments, :hours]
|
@default_columns_names ||= [:project, :spent_on, :user, :activity, :issue, :comments, :hours]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def results_scope(options={})
|
||||||
|
order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
|
||||||
|
|
||||||
|
TimeEntry.visible.
|
||||||
|
where(statement).
|
||||||
|
order(order_option).
|
||||||
|
joins(joins_for_order_statement(order_option.join(',')))
|
||||||
|
end
|
||||||
|
|
||||||
# Accepts :from/:to params as shortcut filters
|
# Accepts :from/:to params as shortcut filters
|
||||||
def build_from_params(params)
|
def build_from_params(params)
|
||||||
super
|
super
|
||||||
|
|
|
@ -559,6 +559,24 @@ class TimelogControllerTest < ActionController::TestCase
|
||||||
assert_select "td.#{field_name}", :text => 'CF Value'
|
assert_select "td.#{field_name}", :text => 'CF Value'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_index_with_time_entry_custom_field_sorting
|
||||||
|
field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field')
|
||||||
|
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 1'})
|
||||||
|
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 3'})
|
||||||
|
TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 2'})
|
||||||
|
field_name = "cf_#{field.id}"
|
||||||
|
|
||||||
|
get :index, :c => ["hours", field_name], :sort => field_name
|
||||||
|
assert_response :success
|
||||||
|
assert_include field_name.to_sym, assigns(:query).column_names
|
||||||
|
assert_select "th a.sort", :text => 'String Field'
|
||||||
|
|
||||||
|
# Make sure that values are properly sorted
|
||||||
|
values = assigns(:entries).map {|e| e.custom_field_value(field)}.compact
|
||||||
|
assert_equal 3, values.size
|
||||||
|
assert_equal values.sort, values
|
||||||
|
end
|
||||||
|
|
||||||
def test_index_atom_feed
|
def test_index_atom_feed
|
||||||
get :index, :project_id => 1, :format => 'atom'
|
get :index, :project_id => 1, :format => 'atom'
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
|
Loading…
Reference in New Issue