Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#32813] Cost reports should include work package children #17720

Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class WorkPackageSpentTimeDisplayField extends WorkDisplayField {
),
)
.search(
`fields[]=WorkPackageId&operators[WorkPackageId]=%3D&values[WorkPackageId]=${wpID}&set_filter=1`,
`fields[]=WorkPackageId&operators[WorkPackageId]=%3D_child_work_packages&values[WorkPackageId]=${wpID}&set_filter=1`,
)
.toString();

Expand Down
25 changes: 16 additions & 9 deletions modules/reporting/app/models/cost_query/filter/work_package_id.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
Expand Down Expand Up @@ -31,6 +33,10 @@ def self.label
WorkPackage.model_name.human
end

def self.available_operators
["=", "!", "=_child_work_packages", "!_child_work_packages"].map(&:to_operator)
end

def self.available_values(*)
WorkPackage
.where(project_id: Project.allowed_to(User.current, :view_work_packages))
Expand All @@ -39,27 +45,28 @@ def self.available_values(*)
.map { |id, subject| [text_for_tuple(id, subject), id] }
end

def self.available_operators
["="].map(&:to_operator)
end

##
# Overwrites Report::Filter::Base self.label_for_value method
# to achieve a more performant implementation
def self.label_for_value(value)
return nil unless value.to_i.to_s == value.to_s # we expect an work_package-id

work_package = WorkPackage.find(value.to_i)
[text_for_work_package(work_package), work_package.id] if work_package and work_package.visible?(User.current)
[text_for_work_package(work_package), work_package.id] if work_package&.visible?(User.current)
end

def self.text_for_tuple(id, subject)
str = "##{id} "
str << (subject.length > 30 ? subject.first(26) + "..." : subject)
str << (subject.length > 30 ? "#{subject.first(26)}..." : subject)
end

def self.text_for_work_package(i)
i = i.first if i.is_a? Array
text_for_touble(i.id, i.subject)
def self.text_for_work_package(work_package_or_work_package_list)
wp = if work_package_or_work_package_list.is_a?(Array)
work_package_or_work_package_list.first
else
work_package_or_work_package_list
end

text_for_tuple(wp.id, wp.subject)
end
end
26 changes: 26 additions & 0 deletions modules/reporting/app/models/cost_query/operator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,30 @@ def modify(query, field, *values)
query
end
end

new "=_child_work_packages", validate: :integers, label: :label_is_work_package_with_descendants do
def modify(query, field, *values)
wp_ids = []
values.each do |value|
wp_ids += ([value] << WorkPackage.find(value).descendants.map(&:id))
end
"=".to_operator.modify query, field, wp_ids
rescue ActiveRecord::RecordNotFound
query
end
end

new "!_child_work_packages", validate: :integers, label: :label_is_not_work_package_with_descendants do
def modify(query, field, *values)
wp_ids = []
values.each do |value|
value.to_s.split(",").each do |id|
wp_ids += ([id] << WorkPackage.find(id).descendants.map(&:id))
klaustopher marked this conversation as resolved.
Show resolved Hide resolved
end
end
"!".to_operator.modify query, field, wp_ids
rescue ActiveRecord::RecordNotFound
query
end
end
end
2 changes: 2 additions & 0 deletions modules/reporting/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ en:
label_greater: ">"
label_is_not_project_with_subprojects: "is not (includes subprojects)"
label_is_project_with_subprojects: "is (includes subprojects)"
label_is_work_package_with_descendants: "is (includes descendants)"
label_is_not_work_package_with_descendants: "is not (includes descendants)"
label_work_package_attributes: "Work package attributes"
label_less: "<"
label_logged_by_reporting: "Logged by"
Expand Down
Loading
Loading