diff --git a/app/models/cost_query/filter/permission_filter.rb b/app/models/cost_query/filter/permission_filter.rb index cbcb27de50..652053ad6d 100644 --- a/app/models/cost_query/filter/permission_filter.rb +++ b/app/models/cost_query/filter/permission_filter.rb @@ -6,24 +6,25 @@ class CostQuery::Filter::PermissionFilter < CostQuery::Filter::Base initialize_query_with { |query| query.filter self.to_s.demodulize.to_sym } def permission_statement(permission) - User.current.allowed_for(permission).gsub(/(user|project)s?\.id/, 'entries.\1_id') + User.current.allowed_for(permission).gsub(/(user|project)s?\.id/, '\1_id') end - + def permission_for(type) - "(entries.type != '#{type.capitalize}Entry' " \ - "OR #{permission_statement :"view_own_#{type}_entries"} " \ + "(#{permission_statement :"view_own_#{type}_entries"} " \ "OR #{permission_statement :"view_#{type}_entries"})" end + def display_costs + "(#{permission_statement :view_hourly_rates} " \ + "AND #{permission_statement :view_cost_rates}) OR (#{permission_statement :view_own_hourly_rate})" + end + def sql_statement super.tap do |query| - if User.current.admin? - query.default_select :display_costs => '1' - else - query.where permission_for('time') - query.where permission_for('cost') - query.default_select :display_costs => "(#{permission_statement :view_hourly_rates} " \ - "AND #{permission_statement :view_cost_rates}) OR (#{permission_statement :view_own_hourly_rate})" + query.default_select :display_costs => 'sum(display_costs)' + query.from.each_subselect do |sub| + sub.where permission_for(sub == query.from.first ? 'time' : 'cost') + sub.default_select :display_costs => switch(display_costs => '1', :else => 0) end end end diff --git a/app/models/cost_query/sql_statement.rb b/app/models/cost_query/sql_statement.rb index 661416775c..1b9426b1d6 100644 --- a/app/models/cost_query/sql_statement.rb +++ b/app/models/cost_query/sql_statement.rb @@ -1,4 +1,24 @@ class CostQuery::SqlStatement + class Union + attr_accessor :first, :second, :as + def initialize(first, second, as = nil) + @first, @second, @as = first, second, as + end + + def to_s + "((#{first}) UNION (#{second}))#{" AS #{as}" if as}" + end + + def each_subselect + yield first + yield second + end + + def gsub(*args, &block) + to_s.gsub(*args, &block) + end + end + include CostQuery::QueryUtils COMMON_FIELDS = %w[ @@ -94,7 +114,7 @@ class CostQuery::SqlStatement # @param [CostQuery::SqlStatement] other Second part of the union # @return [String] The sql query. def union(other, as = nil) - "((#{self}) UNION (#{other}))#{" AS #{as}" if as}" + Union.new(self, other, as) end ##