From 7237f25cc0c4c18dce45b1b900464c758b1da110 Mon Sep 17 00:00:00 2001 From: Jens Kraemer Date: Sun, 30 Oct 2022 02:46:15 +0100 Subject: [PATCH] estimated remaining hours issue query column --- app/helpers/queries_helper.rb | 4 ++-- app/models/issue_query.rb | 25 ++++++++++++++++++++++++- config/locales/de.yml | 1 + config/locales/en.yml | 1 + test/unit/query_test.rb | 28 ++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb index 38d72bbc6d..0eb0e1fcb7 100644 --- a/app/helpers/queries_helper.rb +++ b/app/helpers/queries_helper.rb @@ -186,7 +186,7 @@ module QueriesHelper def total_tag(column, value) label = content_tag('span', "#{column.caption}:") value = - if [:hours, :spent_hours, :total_spent_hours, :estimated_hours, :total_estimated_hours].include? column.name + if [:hours, :spent_hours, :total_spent_hours, :estimated_hours, :total_estimated_hours, :estimated_remaining_hours].include? column.name format_hours(value) else format_object(value) @@ -265,7 +265,7 @@ module QueriesHelper 'span', value.to_s(item) {|other| link_to_issue(other, :subject => false, :tracker => false)}.html_safe, :class => value.css_classes_for(item)) - when :hours, :estimated_hours, :total_estimated_hours + when :hours, :estimated_hours, :total_estimated_hours, :estimated_remaining_hours format_hours(value) when :spent_hours link_to_if(value > 0, format_hours(value), project_time_entries_path(item.project, :issue_id => "#{item.id}")) diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 205084074f..f000a4789a 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -18,6 +18,22 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class IssueQuery < Query + class EstimatedRemainingHoursColumn < QueryColumn + COLUMN_SQL = Arel.sql("COALESCE(#{Issue.table_name}.estimated_hours, 0) * (100 - COALESCE(#{Issue.table_name}.done_ratio, 0)) / 100") + + def initialize + super :estimated_remaining_hours, totalable: true, sortable: COLUMN_SQL + end + + def value(object) + (object.estimated_hours || 0) * (100 - (object.done_ratio || 0)) / 100 + end + + def value_object(object) + value(object) + end + end + self.queried_class = Issue self.view_permission = :view_issues @@ -49,6 +65,7 @@ class IssueQuery < Query QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", :totalable => true), + EstimatedRemainingHoursColumn.new, QueryColumn.new( :total_estimated_hours, :sortable => @@ -324,7 +341,9 @@ class IssueQuery < Query end disabled_fields = Tracker.disabled_core_fields(trackers).map {|field| field.sub(/_id$/, '')} - disabled_fields << "total_estimated_hours" if disabled_fields.include?("estimated_hours") + if disabled_fields.include?("estimated_hours") + disabled_fields += %w[total_estimated_hours estimated_remaining_hours] + end @available_columns.reject! do |column| disabled_fields.include?(column.name.to_s) end @@ -364,6 +383,10 @@ class IssueQuery < Query map_total(scope.sum(:estimated_hours)) {|t| t.to_f.round(2)} end + def total_for_estimated_remaining_hours(scope) + map_total(scope.sum(EstimatedRemainingHoursColumn::COLUMN_SQL)) {|t| t.to_f.round(2)} + end + # Returns sum of all the issue's time entries hours def total_for_spent_hours(scope) total = scope.joins(:time_entries). diff --git a/config/locales/de.yml b/config/locales/de.yml index bcfbe9b7d7..b6cfef1912 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -398,6 +398,7 @@ de: field_watcher: Beobachter field_default_assigned_to: Standardbearbeiter field_unique_id: Eindeutige ID + field_estimated_remaining_hours: Geschätzter verbleibender Aufwand general_csv_decimal_separator: ',' general_csv_encoding: ISO-8859-1 diff --git a/config/locales/en.yml b/config/locales/en.yml index 335614dfbe..bb68bd9646 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -418,6 +418,7 @@ en: field_default_issue_query: Default issue query field_default_project_query: Default project query field_default_time_entry_activity: Default spent time activity + field_estimated_remaining_hours: Estimated remaining time setting_app_title: Application title setting_welcome_text: Welcome text diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 1591e985ef..c95de3bfca 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -2029,6 +2029,11 @@ class QueryTest < ActiveSupport::TestCase assert_include :estimated_hours, q.available_totalable_columns.map(&:name) end + def test_available_totalable_columns_should_include_estimated_remaining_hours + q = IssueQuery.new + assert_include :estimated_remaining_hours, q.available_totalable_columns.map(&:name) + end + def test_available_totalable_columns_should_include_spent_hours User.current = User.find(1) @@ -2102,6 +2107,29 @@ class QueryTest < ActiveSupport::TestCase ) end + def test_total_for_estimated_remaining_hours + Issue.delete_all + Issue.generate!(:estimated_hours => 5.5, :done_ratio => 50) + Issue.generate!(:estimated_hours => 1.1, :done_ratio => 100) + Issue.generate! + + q = IssueQuery.new + assert_equal 2.75, q.total_for(:estimated_remaining_hours) + end + + def test_total_by_group_for_estimated_remaining_hours + Issue.delete_all + Issue.generate!(:estimated_hours => 5.5, :assigned_to_id => 2, :done_ratio => 50) + Issue.generate!(:estimated_hours => 1.1, :assigned_to_id => 3, :done_ratio => 100) + Issue.generate!(:estimated_hours => 3.5, :done_ratio => 0) + + q = IssueQuery.new(:group_by => 'assigned_to') + assert_equal( + {nil => 3.5, User.find(2) => 2.75, User.find(3) => 0}, + q.total_by_group_for(:estimated_remaining_hours) + ) + end + def test_total_for_spent_hours TimeEntry.delete_all TimeEntry.generate!(:hours => 5.5) -- 2.30.2