* moving query patch to proper place * only adding backlogs filter, if backlogs module is active in this project * removing patched methods, that are in core by nowpull/6827/head
parent
f0b34cf378
commit
33136bf640
@ -1,126 +0,0 @@ |
|||||||
require_dependency 'query' |
|
||||||
|
|
||||||
module Backlogs |
|
||||||
module QueryPatch |
|
||||||
def self.included(base) # :nodoc: |
|
||||||
base.extend(ClassMethods) |
|
||||||
base.send(:include, InstanceMethods) |
|
||||||
|
|
||||||
# Same as typing in the class |
|
||||||
base.class_eval do |
|
||||||
unloadable # Send unloadable so it will not be unloaded in development |
|
||||||
base.add_available_column(QueryColumn.new(:story_points, :sortable => "#{Issue.table_name}.story_points")) |
|
||||||
base.add_available_column(QueryColumn.new(:remaining_hours, :sortable => "#{Issue.table_name}.remaining_hours")) |
|
||||||
|
|
||||||
base.add_available_column(QueryColumn.new(:position, |
|
||||||
:sortable => [ |
|
||||||
# sprint startdate |
|
||||||
"coalesce((select start_date from versions where versions.id = issues.fixed_version_id), '1900-01-01')", |
|
||||||
|
|
||||||
# sprint name, in case start dates are the same |
|
||||||
"(select name from versions where versions.id = issues.fixed_version_id)", |
|
||||||
|
|
||||||
# make sure stories with NULL |
|
||||||
# position sort-last |
|
||||||
"(select case when root.position is null then 1 else 0 end from issues root where issues.root_id = root.id)", |
|
||||||
|
|
||||||
# story position |
|
||||||
"(select root.position from issues root where issues.root_id = root.id)", |
|
||||||
|
|
||||||
# story ID, in case positions |
|
||||||
# are the same (SHOULD NOT HAPPEN!). |
|
||||||
# DO NOT CHANGE; root_id is the only field that sorts the same for stories _and_ |
|
||||||
# the tasks it has. |
|
||||||
"issues.root_id", |
|
||||||
|
|
||||||
# order in task tree |
|
||||||
"issues.lft" |
|
||||||
], |
|
||||||
:default_order => 'asc')) |
|
||||||
|
|
||||||
|
|
||||||
alias_method_chain :available_filters, :backlogs_issue_type |
|
||||||
alias_method_chain :sql_for_field, :backlogs_issue_type |
|
||||||
end |
|
||||||
|
|
||||||
end |
|
||||||
|
|
||||||
module InstanceMethods |
|
||||||
def available_filters_with_backlogs_issue_type |
|
||||||
@available_filters = available_filters_without_backlogs_issue_type |
|
||||||
|
|
||||||
if Story.trackers.length == 0 or Task.tracker.blank? |
|
||||||
backlogs_filters = { } |
|
||||||
else |
|
||||||
backlogs_filters = { |
|
||||||
"backlogs_issue_type" => { :type => :list, |
|
||||||
:values => [[l(:story, :scope => [:backlogs]), "story"], [l(:task, :scope => [:backlogs]), "task"], [l(:impediment, :scope => [:backlogs]), "impediment"], [l(:any, :scope => [:backlogs]), "any"]], |
|
||||||
:order => 20 } |
|
||||||
} |
|
||||||
end |
|
||||||
|
|
||||||
return @available_filters.merge(backlogs_filters) |
|
||||||
end |
|
||||||
|
|
||||||
def sql_for_field_with_backlogs_issue_type(field, operator, v, db_table, db_field, is_custom_filter=false) |
|
||||||
if field == "backlogs_issue_type" |
|
||||||
db_table = Issue.table_name |
|
||||||
|
|
||||||
sql = [] |
|
||||||
|
|
||||||
selected_values = values_for(field) |
|
||||||
selected_values = ['story', 'task'] if selected_values.include?('any') |
|
||||||
|
|
||||||
story_trackers = Story.trackers.collect{|val| "#{val}"}.join(",") |
|
||||||
all_trackers = (Story.trackers + [Task.tracker]).collect{|val| "#{val}"}.join(",") |
|
||||||
|
|
||||||
selected_values.each { |val| |
|
||||||
case val |
|
||||||
when "story" |
|
||||||
sql << "(#{db_table}.tracker_id in (#{story_trackers}))" |
|
||||||
when "task" |
|
||||||
sql << "(#{db_table}.tracker_id = #{Task.tracker} and not #{db_table}.parent_id is NULL)" |
|
||||||
when "impediment" |
|
||||||
sql << "(#{db_table}.id in ( |
|
||||||
select issue_from_id |
|
||||||
from issue_relations ir |
|
||||||
join issues blocked |
|
||||||
on |
|
||||||
blocked.id = ir.issue_to_id |
|
||||||
and blocked.tracker_id in (#{all_trackers}) |
|
||||||
where ir.relation_type = 'blocks' |
|
||||||
) and #{db_table}.parent_id is NULL)" |
|
||||||
end |
|
||||||
} |
|
||||||
|
|
||||||
case operator |
|
||||||
when "=" |
|
||||||
sql = sql.join(" or ") |
|
||||||
when "!" |
|
||||||
sql = "not (" + sql.join(" or ") + ")" |
|
||||||
end |
|
||||||
|
|
||||||
return sql |
|
||||||
|
|
||||||
else |
|
||||||
return sql_for_field_without_backlogs_issue_type(field, operator, v, db_table, db_field, is_custom_filter) |
|
||||||
end |
|
||||||
|
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
module ClassMethods |
|
||||||
# Setter for +available_columns+ that isn't provided by the core. |
|
||||||
def available_columns=(v) |
|
||||||
self.available_columns = (v) |
|
||||||
end |
|
||||||
|
|
||||||
# Method to add a column to the +available_columns+ that isn't provided by the core. |
|
||||||
def add_available_column(column) |
|
||||||
self.available_columns << (column) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
Query.send(:include, Backlogs::QueryPatch) unless Query.included_modules.include? Backlogs::QueryPatch |
|
@ -0,0 +1,114 @@ |
|||||||
|
require_dependency 'query' |
||||||
|
|
||||||
|
module RedmineBacklogs::Patches::QueryPatch |
||||||
|
def self.included(base) |
||||||
|
base.class_eval do |
||||||
|
unloadable |
||||||
|
|
||||||
|
include InstanceMethods |
||||||
|
|
||||||
|
add_available_column(QueryColumn.new(:story_points, :sortable => "#{Issue.table_name}.story_points")) |
||||||
|
add_available_column(QueryColumn.new(:remaining_hours, :sortable => "#{Issue.table_name}.remaining_hours")) |
||||||
|
|
||||||
|
add_available_column(QueryColumn.new(:position, :default_order => 'asc', :sortable => [ |
||||||
|
# sprint startdate |
||||||
|
"coalesce((select start_date from versions where versions.id = issues.fixed_version_id), '1900-01-01')", |
||||||
|
|
||||||
|
# sprint name, in case start dates are the same |
||||||
|
"(select name from versions where versions.id = issues.fixed_version_id)", |
||||||
|
|
||||||
|
# make sure stories with NULL |
||||||
|
# position sort-last |
||||||
|
"(select case when root.position is null then 1 else 0 end from issues root where issues.root_id = root.id)", |
||||||
|
|
||||||
|
# story position |
||||||
|
"(select root.position from issues root where issues.root_id = root.id)", |
||||||
|
|
||||||
|
# story ID, in case positions |
||||||
|
# are the same (SHOULD NOT HAPPEN!). |
||||||
|
# DO NOT CHANGE; root_id is the only field that sorts the same for stories _and_ |
||||||
|
# the tasks it has. |
||||||
|
"issues.root_id", |
||||||
|
|
||||||
|
# order in task tree |
||||||
|
"issues.lft" |
||||||
|
])) |
||||||
|
|
||||||
|
alias_method_chain :available_filters, :backlogs_issue_type |
||||||
|
alias_method_chain :sql_for_field, :backlogs_issue_type |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
module InstanceMethods |
||||||
|
def available_filters_with_backlogs_issue_type |
||||||
|
available_filters_without_backlogs_issue_type.tap do |filters| |
||||||
|
if backlogs_configured? and backlogs_enabled? |
||||||
|
filters["backlogs_issue_type"] = { |
||||||
|
:type => :list, |
||||||
|
:values => [[l(:story, :scope => [:backlogs]), "story"], |
||||||
|
[l(:task, :scope => [:backlogs]), "task"], |
||||||
|
[l(:impediment, :scope => [:backlogs]), "impediment"], |
||||||
|
[l(:any, :scope => [:backlogs]), "any"]], |
||||||
|
:order => 20 |
||||||
|
} |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def sql_for_field_with_backlogs_issue_type(field, operator, v, db_table, db_field, is_custom_filter=false) |
||||||
|
if field == "backlogs_issue_type" |
||||||
|
db_table = Issue.table_name |
||||||
|
|
||||||
|
sql = [] |
||||||
|
|
||||||
|
selected_values = values_for(field) |
||||||
|
selected_values = ['story', 'task'] if selected_values.include?('any') |
||||||
|
|
||||||
|
story_trackers = Story.trackers.collect { |val| "#{val}" }.join(",") |
||||||
|
all_trackers = (Story.trackers + [Task.tracker]).collect { |val| "#{val}" }.join(",") |
||||||
|
|
||||||
|
selected_values.each do |val| |
||||||
|
case val |
||||||
|
when "story" |
||||||
|
sql << "(#{db_table}.tracker_id IN (#{story_trackers}))" |
||||||
|
when "task" |
||||||
|
sql << "(#{db_table}.tracker_id = #{Task.tracker} AND NOT #{db_table}.parent_id IS NULL)" |
||||||
|
when "impediment" |
||||||
|
sql << "(#{db_table}.id IN ( |
||||||
|
select issue_from_id |
||||||
|
FROM issue_relations ir |
||||||
|
JOIN issues blocked |
||||||
|
ON |
||||||
|
blocked.id = ir.issue_to_id |
||||||
|
AND blocked.tracker_id IN (#{all_trackers}) |
||||||
|
WHERE ir.relation_type = 'blocks' |
||||||
|
) AND #{db_table}.parent_id IS NULL)" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
case operator |
||||||
|
when "=" |
||||||
|
sql = sql.join(" OR ") |
||||||
|
when "!" |
||||||
|
sql = "NOT (" + sql.join(" OR ") + ")" |
||||||
|
end |
||||||
|
|
||||||
|
sql |
||||||
|
else |
||||||
|
sql_for_field_without_backlogs_issue_type(field, operator, v, db_table, db_field, is_custom_filter) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
protected |
||||||
|
|
||||||
|
def backlogs_configured? |
||||||
|
Story.trackers.present? and Task.tracker.present? |
||||||
|
end |
||||||
|
|
||||||
|
def backlogs_enabled? |
||||||
|
project.blank? or project.module_enabled?(:backlogs) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
Query.send(:include, RedmineBacklogs::Patches::QueryPatch) |
Loading…
Reference in new issue