Redmine.org-4776-Estimated-time-patch_v1.1-for-RM-3.1.0.patch

Olivier Houdas, 2015-08-14 16:14

Download (9.71 KB)

View differences:

app/controllers/issues_controller.rb Wed Jun 24 19:28:42 2015 +0200
65 65
      end
66 66

  
67 67
      @issue_count = @query.issue_count
68
      #[OHO-start] time info in issue lists
69
      @issue_sum_estimated = @query.issue_sum_estimated
70
      @issue_sum_spent = @query.issue_sum_spent
71
      #[OHO-end]
68 72
      @issue_pages = Paginator.new @issue_count, @limit, params['page']
69 73
      @offset ||= @issue_pages.offset
70 74
      @issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
......
72 76
                              :offset => @offset,
73 77
                              :limit => @limit)
74 78
      @issue_count_by_group = @query.issue_count_by_group
75

  
79
      #[OHO-start] time info in issue lists
80
      @issue_sum_spent_by_group = @query.issue_sum_spent_by_group
81
      @issue_sum_estimated_by_group = @query.issue_sum_estimated_by_group
82
      #[OHO-end]
76 83
      respond_to do |format|
77 84
        format.html { render :template => 'issues/index', :layout => !request.xhr? }
78 85
        format.api  {
app/helpers/issues_helper.rb Wed Jun 24 19:28:42 2015 +0200
32 32
    end
33 33
  end
34 34

  
35
  def grouped_issue_list(issues, query, issue_count_by_group, &block)
35
#[OHO-start] modified function to handle 2 more variables for estimated and spent time
36
  def grouped_issue_list(issues, query, issue_count_by_group, issue_sum_estimated_by_group, issue_sum_spent_by_group, &block)
36 37
    previous_group, first = false, true
37 38
    issue_list(issues) do |issue, level|
38 39
      group_name = group_count = nil
......
43 44
          group_name = column_content(query.group_by_column, issue)
44 45
        end
45 46
        group_name ||= ""
46
        group_count = issue_count_by_group[group]
47
        issue_count_by_group.respond_to?(:has_key?) ? group_count = issue_count_by_group[group] : group_count = issue_count_by_group
48
        issue_sum_estimated_by_group.respond_to?(:has_key?) ? group_estimated_hours = issue_sum_estimated_by_group[group] : group_estimated_hours = 0
49
        issue_sum_spent_by_group.respond_to?(:has_key?) ? group_spent_hours = issue_sum_spent_by_group[group] : group_spent_hours = 0
50
        group_estimated_hours = 0 if group_estimated_hours.nil?
51
        group_spent_hours = 0 if group_spent_hours.nil?
47 52
      end
48
      yield issue, level, group_name, group_count
53
      yield issue, level, group_name, group_count, group_estimated_hours, group_spent_hours
49 54
      previous_group, first = group, false
50 55
    end
51 56
  end
57
#[OHO-end] 
58

  
52 59

  
53 60
  # Renders a HTML/CSS tooltip
54 61
  #
app/models/issue_query.rb Wed Jun 24 19:28:42 2015 +0200
297 297
    raise StatementInvalid.new(e.message)
298 298
  end
299 299

  
300
  #[OHO-start] time info for issue lists
301
  # Returns sum of all the issue's estimated_hours 
302
  def issue_sum_estimated
303
    Issue.visible.joins(:status, :project).where(statement).sum(:estimated_hours)
304
  rescue ::ActiveRecord::StatementInvalid => e
305
    raise StatementInvalid.new(e.message)  
306
  end
307

  
308
  # Returns sum of all the issue's spent time 
309
  def issue_sum_spent
310
    TimeEntry.visible.joins(:issue, :project).where(statement).sum(:hours)
311
  rescue ::ActiveRecord::StatementInvalid => e
312
    raise StatementInvalid.new(e.message)
313
  end
314
  #[OHO-end]
315

  
316

  
300 317
  # Returns the issue count by group or nil if query is not grouped
301 318
  def issue_count_by_group
302 319
    r = nil
......
322 339
    raise StatementInvalid.new(e.message)
323 340
  end
324 341

  
342
  #[OHO-start] time info for issue lists
343
  # Returns  sum of the issue's estimated_hours by group or nil if query is not grouped
344
  def issue_sum_estimated_by_group
345
    r = nil
346
    if grouped?
347
      begin
348
        r = Issue.visible. 
349
          joins(:status, :project). 
350
          where(statement).
351
          group(group_by_statement).
352
          joins(joins_for_order_statement(group_by_statement)).
353
          sum(:estimated_hours)
354
      rescue ActiveRecord::RecordNotFound
355
        r= {nil => 0}
356
      end
357
      
358
      c = group_by_column
359
      if c.is_a?(QueryCustomFieldColumn) && r.respond_to?(:has_keys?)
360
        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
361
      end
362
    end
363
    r
364
  rescue ::ActiveRecord::StatementInvalid => e
365
    raise StatementInvalid.new(e.message)
366
  end
367

  
368
  # Returns  sum of the issue's spent time by group or nil if query is not grouped
369
  def issue_sum_spent_by_group
370
    r = nil
371
    # Spent hours not available for project grouping as it leads to an ambiguous column name SQL issue
372
    if grouped? && group_by_statement != "project"
373
      begin
374
        # Problem with parent/child tasks: time is counted for both parents and children
375
        r = TimeEntry.visible.
376
          joins(:issue, :project).
377
          where(statement).
378
          joins(joins_for_order_statement(group_by_statement)).
379
          group(group_by_statement).
380
          sum(:hours)
381
      rescue ActiveRecord::RecordNotFound
382
        r= {nil => 0}
383
      end
384
      
385
      c = group_by_column
386
      if c.is_a?(QueryCustomFieldColumn) && r.respond_to?(:has_keys?)
387
        r = r.keys.inject({}) {|h, k| h[c.custom_field.cast_value(k)] = r[k]; h}
388
      end
389
    end
390
    r
391
  rescue ::ActiveRecord::StatementInvalid => e
392
    raise StatementInvalid.new(e.message)
393
  end
394
  #[OHO-end]
395

  
325 396
  # Returns the issues
326 397
  # Valid options are :order, :offset, :limit, :include, :conditions
327 398
  def issues(options={})
app/models/time_entry.rb Wed Jun 24 19:28:42 2015 +0200
23 23
  belongs_to :issue
24 24
  belongs_to :user
25 25
  belongs_to :activity, :class_name => 'TimeEntryActivity'
26
#[OHO-start] Added groupable fields to be able to group on those fields for spent time calculation in grouped issue lists (issue_query.rb)
27
  belongs_to :status, :class_name => 'IssueStatus'
28
  belongs_to :author, :class_name => 'User'
29
  belongs_to :assigned_to, :class_name => 'Principal'
30
  belongs_to :fixed_version, :class_name => 'Version'
31
  belongs_to :priority, :class_name => 'IssuePriority'
32
  belongs_to :category, :class_name => 'IssueCategory'
33
  belongs_to :tracker, :class_name => 'Tracker'
34
#[OHO-end]
26 35

  
27 36
  attr_protected :user_id, :tyear, :tmonth, :tweek
28 37

  
app/views/issues/_list.html.erb Wed Jun 24 19:28:42 2015 +0200
15 15
    </tr>
16 16
  </thead>
17 17
  <tbody>
18
  <% grouped_issue_list(issues, @query, @issue_count_by_group) do |issue, level, group_name, group_count| -%>
18
  <% #[OHO-start] time info in issue lists: modified to add variables
19
   grouped_issue_list(issues, @query, @issue_count_by_group, @issue_sum_estimated_by_group, @issue_sum_spent_by_group) do |issue, level, group_name, group_count, group_estimated_hours, group_spent_hours| 
20
   #[OHO-end]
21
   -%>
19 22
  <% if group_name %>
20 23
    <% reset_cycle %>
21 24
    <tr class="group open">
22 25
      <td colspan="<%= query.inline_columns.size + 2 %>">
23 26
        <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
24 27
        <%= group_name %> <span class="count"><%= group_count %></span>
28
        <% #[OHO-start] time info in issue lists
29
        if (group_estimated_hours > 0 || group_spent_hours > 0) %>(<%
30
          if group_estimated_hours > 0 
31
        %><%= l(:field_estimated_hours) %>: <%= l_hours(group_estimated_hours) %><%
32
          end
33
          if group_spent_hours > 0 && group_estimated_hours > 0 %>, <%
34
          end
35
          if group_spent_hours > 0 %><%= l(:label_spent_time) %>: <%= l_hours(group_spent_hours) %><%
36
          end%>)<%
37
        end
38
        #[OHO-end]
39
        %>
25 40
        <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
26 41
                             "toggleAllRowGroups(this)", :class => 'toggle-all') %>
27 42
      </td>
......
42 57
  </tbody>
43 58
</table>
44 59
</div>
45
<% end -%>
60
<% end %>
61
<%
62
  #[OHO] time info in issue lists
63
%>
64
<p align="right">
65
    <b><%= l(:field_estimated_hours) %>: <b><%= l_hours(@issue_sum_estimated) %></b><% if @issue_sum_spent.present? %>
66
         , <%= l(:label_spent_time) %>: <b><%= l_hours(@issue_sum_spent) %></b><% end %>)
67

  
68
</p>
app/models/issue_query.rb Fri Aug 14 16:11:16 2015 +0200
396 396
  # Returns the issues
397 397
  # Valid options are :order, :offset, :limit, :include, :conditions
398 398
  def issues(options={})
399
    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?)
399
# [OHO-2015-08-14] Added .join(',').to_s.split(',').uniq to remove duplicates
400
    order_option = [group_by_sort_order, options[:order]].flatten.reject(&:blank?).join(',').to_s.split(',').uniq
400 401

  
401 402
    scope = Issue.visible.
402 403
      joins(:status, :project).