61 |
61 |
end,
|
62 |
62 |
:default_order => 'desc'),
|
63 |
63 |
QueryColumn.new(:done_ratio, :sortable => "#{Issue.table_name}.done_ratio", :groupable => true),
|
|
64 |
QueryColumn.new(
|
|
65 |
:spent_time_ratio,
|
|
66 |
:sortable =>
|
|
67 |
lambda do
|
|
68 |
"COALESCE((" \
|
|
69 |
" SELECT ROUND(CAST(COALESCE(SUM(hours), 0) / NULLIF(#{Issue.table_name}.estimated_hours, 0) * 100 AS DECIMAL(4,2)), 2) " \
|
|
70 |
" FROM #{TimeEntry.table_name}" \
|
|
71 |
" WHERE issue_id = #{Issue.table_name}.id), NULL)"
|
|
72 |
end,
|
|
73 |
:default_order => 'desc'),
|
|
74 |
QueryColumn.new(
|
|
75 |
:total_spent_time_ratio,
|
|
76 |
:sortable =>
|
|
77 |
lambda do
|
|
78 |
"COALESCE(ROUND(CAST(" \
|
|
79 |
"COALESCE((SELECT SUM(hours)" \
|
|
80 |
" FROM #{TimeEntry.table_name}" \
|
|
81 |
" JOIN #{Project.table_name} ON #{Project.table_name}.id = #{TimeEntry.table_name}.project_id" \
|
|
82 |
" JOIN #{Issue.table_name} subtasks ON subtasks.id = #{TimeEntry.table_name}.issue_id" \
|
|
83 |
" WHERE (#{TimeEntry.visible_condition(User.current)})" \
|
|
84 |
" AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" \
|
|
85 |
" / " \
|
|
86 |
"NULLIF((SELECT SUM(estimated_hours)" \
|
|
87 |
" FROM #{Issue.table_name} subtasks" \
|
|
88 |
" WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')}" \
|
|
89 |
" AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" \
|
|
90 |
"* 100 AS DECIMAL(4,2)), 2), NULL)"
|
|
91 |
end,
|
|
92 |
:default_order => 'desc'),
|
64 |
93 |
TimestampQueryColumn.new(:created_on, :sortable => "#{Issue.table_name}.created_on",
|
65 |
94 |
:default_order => 'desc', :groupable => true),
|
66 |
95 |
TimestampQueryColumn.new(:closed_on, :sortable => "#{Issue.table_name}.closed_on",
|
... | ... | |
203 |
232 |
end
|
204 |
233 |
|
205 |
234 |
add_available_filter "done_ratio", :type => :integer
|
|
235 |
add_available_filter "spent_time_ratio", :type => :float
|
|
236 |
add_available_filter "total_spent_time_ratio", :type => :float
|
206 |
237 |
|
207 |
238 |
if User.current.allowed_to?(:set_issues_private, nil, :global => true) ||
|
208 |
239 |
User.current.allowed_to?(:set_own_issues_private, nil, :global => true)
|
... | ... | |
508 |
539 |
"WHERE issue_id = #{Issue.table_name}.id), 0) #{sql_op}"
|
509 |
540 |
end
|
510 |
541 |
|
|
542 |
def sql_for_spent_time_ratio_field(field, operator, value)
|
|
543 |
first, second = value.first.to_f, value.second.to_f
|
|
544 |
sql_op =
|
|
545 |
case operator
|
|
546 |
when "=", ">=", "<=" then "#{operator} #{first}"
|
|
547 |
when "><" then "BETWEEN #{first} AND #{second}"
|
|
548 |
when "*" then ">= 0"
|
|
549 |
when "!*" then "IS NULL"
|
|
550 |
else
|
|
551 |
return nil
|
|
552 |
end
|
|
553 |
"COALESCE((" +
|
|
554 |
"SELECT ROUND(CAST(COALESCE(SUM(hours), 0) / NULLIF(#{Issue.table_name}.estimated_hours, 0) * 100 AS DECIMAL(4,2)), 2) " +
|
|
555 |
"FROM #{TimeEntry.table_name} " +
|
|
556 |
"WHERE issue_id = #{Issue.table_name}.id), NULL) #{sql_op}"
|
|
557 |
end
|
|
558 |
|
|
559 |
def sql_for_total_spent_time_ratio_field(field, operator, value)
|
|
560 |
first, second = value.first.to_f, value.second.to_f
|
|
561 |
sql_op =
|
|
562 |
case operator
|
|
563 |
when "=", ">=", "<=" then "#{operator} #{first}"
|
|
564 |
when "><" then "BETWEEN #{first} AND #{second}"
|
|
565 |
when "*" then ">= 0"
|
|
566 |
when "!*" then "IS NULL"
|
|
567 |
else
|
|
568 |
return nil
|
|
569 |
end
|
|
570 |
"COALESCE(ROUND(CAST(" +
|
|
571 |
"COALESCE((SELECT SUM(hours)" +
|
|
572 |
" FROM #{TimeEntry.table_name}" +
|
|
573 |
" JOIN #{Project.table_name} ON #{Project.table_name}.id = #{TimeEntry.table_name}.project_id" +
|
|
574 |
" JOIN #{Issue.table_name} subtasks ON subtasks.id = #{TimeEntry.table_name}.issue_id" +
|
|
575 |
" WHERE (#{TimeEntry.visible_condition(User.current)})" +
|
|
576 |
" AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" +
|
|
577 |
" / " +
|
|
578 |
"NULLIF((SELECT SUM(estimated_hours)" +
|
|
579 |
" FROM #{Issue.table_name} subtasks" +
|
|
580 |
" WHERE #{Issue.visible_condition(User.current).gsub(/\bissues\b/, 'subtasks')}" +
|
|
581 |
" AND subtasks.root_id = #{Issue.table_name}.root_id AND subtasks.lft >= #{Issue.table_name}.lft AND subtasks.rgt <= #{Issue.table_name}.rgt), 0)" +
|
|
582 |
" * 100 AS DECIMAL(4,2)), 2), NULL) #{sql_op}"
|
|
583 |
end
|
|
584 |
|
511 |
585 |
def sql_for_watcher_id_field(field, operator, value)
|
512 |
586 |
db_table = Watcher.table_name
|
513 |
587 |
me, others = value.partition {|id| ['0', User.current.id.to_s].include?(id)}
|