Skip to content
8 changes: 6 additions & 2 deletions lib/api/v3/utilities/resource_link_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ def make_link(record)

private

# Since not all things are equally named between APIv3 and the rails code,
# we need to convert some names manually
def determine_path_method(record)
# since not all things are equally named between APIv3 and the rails code,
# we need to convert some names manually
# Some objects offer a name for the API, use if available:
return record.api_resource_link_name if record.respond_to?(:api_resource_link_name)

# Manual mapping:
case record
when Project
:project
Expand Down
8 changes: 8 additions & 0 deletions modules/backlogs/app/models/agile/sprint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,13 @@ def visible_to?(project)
end

def to_s = name

def api_resource_link_name
# This is necessary to make the API resource links match the sprint property name.
# E.g., when grouping by a sprint in the WP table.
# Since the property is called `sprint`, but the model_name is `agile_sprint`, there would
# otherwise be a mismatch. Avoid that:
:sprint
end
end
end
1 change: 1 addition & 0 deletions modules/backlogs/lib/open_project/backlogs/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ def self.settings
filter OpenProject::Backlogs::WorkPackageFilter

select OpenProject::Backlogs::QueryBacklogsSelect
select OpenProject::Backlogs::WorkPackageSprintSelect
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module OpenProject::Backlogs
class WorkPackageSprintSelect < Queries::WorkPackages::Selects::WorkPackageSelect
SORT_ORDER = %w[visible_sprints.name
visible_sprints.start_date
visible_sprints.finish_date].freeze

def self.instances(context = nil)
return [] if context && !context.backlogs_enabled?
return [] unless OpenProject::FeatureDecisions.scrum_projects_active?
return [] unless user_allowed_to_select_sprint?(context)

[new]
end

def self.user_allowed_to_select_sprint?(context)
if context
User.current.allowed_in_project?(:view_sprints, context)
else
User.current.allowed_in_any_project?(:view_sprints)
end
end

def initialize
# Cannot use `association` here since that will break our custom GROUP BY
super(:sprint,
sortable: SORT_ORDER,
groupable_join: sprint_join_with_permissions,
groupable: group_by_statement,
groupable_select: groupable_select)
end

def sortable_join_statement(_query)
sprint_join_with_permissions
end

def groupable_select
group_by_statement
end

def group_by_statement
"visible_sprints.id"
end

private

# Custom outer join to ensure that sprints the user cannot show are treated like
# they are not there at all. Without this, group counts would not match the listed
# work packages.
def sprint_join_with_permissions
<<~SQL.squish
LEFT OUTER JOIN "projects" ON "projects"."id" = "work_packages"."project_id"
LEFT OUTER JOIN (
SELECT
s.id,
s.name,
s.start_date,
s.finish_date,
s.project_id
FROM sprints s
WHERE s.project_id IN (#{projects_with_view_sprints_permissions.to_sql})
) AS visible_sprints
ON visible_sprints.id = work_packages.sprint_id
AND visible_sprints.project_id = work_packages.project_id
SQL
end

def projects_with_view_sprints_permissions
Project.allowed_to(User.current, :view_sprints).select(:id)
end
end
end
Loading
Loading