Index: app/helpers/projects_helper.rb
===================================================================
--- app/helpers/projects_helper.rb (revision 1182)
+++ app/helpers/projects_helper.rb (working copy)
@@ -16,6 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module ProjectsHelper
+ include IssuesHelper
def link_to_version(version, options = {})
return '' unless version && version.is_a?(Version)
link_to version.name, {:controller => 'projects',
@@ -152,9 +153,9 @@
gc.stroke('transparent')
events.each do |i|
if i.is_a?(Issue)
- i_start_date = (i.start_date >= date_from ? i.start_date : date_from )
- i_end_date = (i.due_date <= date_to ? i.due_date : date_to )
- i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
+ i_start_date = (i.total('start_date') >= date_from ? i.total('start_date') : date_from )
+ i_end_date = (i.total('due_date') <= date_to ? i.total('due_date') : date_to )
+ i_done_date = i.total('start_date') + i.total('actual_days')
i_done_date = (i_done_date <= date_from ? date_from : i_done_date )
i_done_date = (i_done_date >= date_to ? date_to : i_done_date )
i_late_date = [i_end_date, Date.today].min if i_start_date < Date.today
@@ -171,7 +172,7 @@
gc.fill('blue')
gc.rectangle(i_left, top, i_left + d_width, top - 6) if d_width > 0
gc.fill('black')
- gc.text(i_left + i_width + 5,top + 1, "#{i.status.name} #{i.done_ratio}%")
+ gc.text(i_left + i_width + 5,top + 1, "#{i.total('status').name} #{i.total('done_ratio')}%")
else
i_left = subject_width + ((i.start_date - date_from)*zoom).floor
gc.fill('green')
Index: app/helpers/issues_helper.rb
===================================================================
--- app/helpers/issues_helper.rb (revision 1182)
+++ app/helpers/issues_helper.rb (working copy)
@@ -27,10 +27,10 @@
@cached_label_priority ||= l(:field_priority)
link_to_issue(issue) + ": #{h(issue.subject)}
" +
- "#{@cached_label_start_date}: #{format_date(issue.start_date)}
" +
- "#{@cached_label_due_date}: #{format_date(issue.due_date)}
" +
+ "#{@cached_label_start_date}: #{format_date(issue.total('start_date'))}
" +
+ "#{@cached_label_due_date}: #{format_date(issue.total('due_date'))}
" +
"#{@cached_label_assigned_to}: #{issue.assigned_to}
" +
- "#{@cached_label_priority}: #{issue.priority.name}"
+ "#{@cached_label_priority}: #{issue.total('priority').name}"
end
def show_detail(detail, no_html=false)
@@ -104,7 +104,109 @@
end
end
end
+
+ def linklist_add_child(elements, no_my, no_child)
+ if elements[no_my]["child"] == -1 #edge
+ elements[no_my]["child"] = no_child
+
+ elements[no_child]["parent"] = no_my
+ my_previous = elements[no_my]["previous"]
+ my_next = elements[no_my]["next"]
+ child_previous = elements[no_child]["previous"]
+ child_next = elements[no_child]["next"]
+ elements[no_my]["previous"] = child_previous
+ elements[no_my]["next"] = child_next
+ elements[child_previous]["next"] = no_my if child_previous != -1
+ elements[child_next]["previous"] = no_my if child_next != -1
+ elements[my_previous]["next"] = my_next if my_previous != -1
+ elements[my_next]["previous"] = my_previous if my_next != -1
+ elements[no_child]["previous"] = -1
+ elements[no_child]["next"] = -1
+ else
+ no_element = elements[no_my]["child"]
+ while elements[no_element]["next"] != -1 #until last
+ no_element = elements[no_element]["next"]
+ end
+ elements[no_element]["next"] = no_child
+
+ elements[no_child]["parent"] = no_my
+ child_previous = elements[no_child]["previous"]
+ child_next = elements[no_child]["next"]
+ elements[child_previous]["next"] = child_next if child_previous != -1
+ elements[child_next]["previous"] = child_previous if child_next != -1
+ elements[no_child]["previous"] = no_element
+ elements[no_child]["next"] = -1
+ end
+
+ elements
+ end
+
+ def make_outline(elements, outline_level, no_my)
+ no_next = no_my
+ while no_next != -1
+ elements[0]["no"] += 1
+ elements[no_next]["no"] = elements[0]["no"]
+ elements[no_next]["issue"].outline_level(outline_level)
+ if elements[no_next]["child"] != -1
+ elements = make_outline(elements, outline_level+1, elements[no_next]["child"])
+ end
+ no_next = elements[no_next]["next"]
+ end
+ elements
+ end
+ def issues_to_outlines(issues)
+ no_used = 0
+ outlines = []
+ outlines << {"no"=>0,"previous"=>-1,"next"=>-1,"parent"=>-1,"child"=>-1}
+ # add edges
+ issues.each do |issue|
+ unless issue.childs && issue.childs.size > 0
+ outlines[no_used]["next"] = no_used + 1
+ outlines << {"no"=>0,"previous"=>no_used,"next"=>-1,"parent"=>-1,"child"=>-1,"issue"=>issue}
+ no_used += 1
+ end
+ end
+ # add non edges
+ issues.each do |issue|
+ if issue.childs && issue.childs.size > 0
+ outlines[no_used]["next"] = no_used + 1
+ outlines << {"no"=>0,"previous"=>no_used,"next"=>-1,"parent"=>-1,"child"=>-1,"issue"=>issue}
+ no_used += 1
+ end
+ end
+ # link family
+ 1.upto(outlines.size-1) do |i|
+ (i+1).upto(outlines.size-1) do |j|
+ if outlines[i]["issue"].parents && (outlines[i]["issue"].parents.size > 0) && (outlines[i]["issue"].parents[0].id == outlines[j]["issue"].id)
+ outlines = linklist_add_child(outlines, j, i)
+ elsif outlines[j]["issue"].parents && (outlines[j]["issue"].parents.size > 0) && (outlines[j]["issue"].parents[0].id == outlines[i]["issue"].id)
+ outlines = linklist_add_child(outlines, i, j)
+ end
+ end
+ end
+ # make outline
+ outlines2 = make_outline(outlines, 1, outlines[0]["next"])
+ # sort
+ outlines2.shift
+ issues = []
+ 1.upto(outlines2.size) do |no|
+ outlines2.each do |outline|
+ if outline["no"] == no
+ issues << outline["issue"]
+ break
+ end
+ end
+ end
+ 0.upto(issues.size-1) do |no|
+ if (no >= issues.size-1) || (issues[no].outline_level >= issues[no+1].outline_level)
+ issues[no].edge(1)
+ end
+ end
+ issues
+ end
+
+
def issues_to_csv(issues, project = nil)
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
export = StringIO.new
@@ -115,6 +217,7 @@
l(:field_project),
l(:field_tracker),
l(:field_priority),
+ l(:field_outline),
l(:field_subject),
l(:field_assigned_to),
l(:field_category),
@@ -132,21 +235,23 @@
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_custom_fields
custom_fields.each {|f| headers << f.name}
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
+ issues = issues_to_outlines(issues)
# csv lines
issues.each do |issue|
fields = [issue.id,
- issue.status.name,
+ issue.total('status').name,
issue.project.name,
issue.tracker.name,
- issue.priority.name,
+ issue.total('priority').name,
+ issue.outline_level,
issue.subject,
issue.assigned_to,
issue.category,
issue.fixed_version,
issue.author.name,
- format_date(issue.start_date),
- format_date(issue.due_date),
- issue.done_ratio,
+ format_date(issue.total('start_date')),
+ format_date(issue.total('due_date')),
+ issue.total('done_ratio'),
issue.estimated_hours,
format_time(issue.created_on),
format_time(issue.updated_on)
Index: app/helpers/queries_helper.rb
===================================================================
--- app/helpers/queries_helper.rb (revision 1182)
+++ app/helpers/queries_helper.rb (working copy)
@@ -32,7 +32,8 @@
cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
show_value(cv)
else
- value = issue.send(column.name)
+# value = issue.send(column.name)
+ value = issue.total(column.name)
if value.is_a?(Date)
format_date(value)
elsif value.is_a?(Time)
Index: app/models/issue.rb
===================================================================
--- app/models/issue.rb (revision 1182)
+++ app/models/issue.rb (working copy)
@@ -223,6 +223,10 @@
def duplicates
relations.select {|r| r.relation_type == IssueRelation::TYPE_DUPLICATES}.collect {|r| r.other_issue(self)}
end
+
+ def duration1
+ (start_date && due_date) ? (due_date - start_date + 1) : 0
+ end
def duration
(start_date && due_date) ? due_date - start_date : 0
@@ -231,10 +235,104 @@
def soonest_start
@soonest_start ||= relations_to.collect{|relation| relation.successor_soonest_start}.compact.min
end
-
+
def self.visible_by(usr)
with_scope(:find => { :conditions => Project.visible_by(usr) }) do
yield
end
end
+
+ def total(filed)
+ filed = filed.to_s
+ if filed == 'done_ratio' || filed == 'planned_days' || filed == 'actual_days'
+ @total_planned_days ||= self.duration1
+ @total_actual_days ||= done_ratio ? (@total_planned_days * done_ratio / 100).floor : 0
+ @total_done_ratio ||= done_ratio
+ else
+ eval("@total_#{filed} ||= #{filed}")
+ end
+ if filed == 'estimated_hours' || filed == 'spent_hours'
+ type = 'sum'
+ elsif filed == 'start_date'
+ type = 'min'
+ elsif filed == 'due_date'
+ type = 'max'
+ elsif filed == 'priority' || filed == 'fixed_version'
+ type = 'max_id'
+ elsif filed == 'status'
+ type = 'min_id'
+ elsif filed == 'done_ratio' || filed == 'planned_days' || filed == 'actual_days'
+ type = 'done_ratio'
+ else
+ return(eval("@total_#{filed}"))
+ end
+ if !eval("@total_#{filed}") || (eval("@total_#{filed}") == 0) || (type == 'max_id') || (type == 'min_id')
+ relations_to.each do |relation|
+ if relation.relation_type == IssueRelation::TYPE_PARENTS
+ othertotal = relation.other_issue(self).total(filed)
+ if ! eval("@total_#{filed}")
+ eval("@total_#{filed} = othertotal")
+ elsif type == 'done_ratio' || type == 'planned_days' || type == 'actual_days'
+ planned_days = relation.other_issue(self).total('duration1')
+ actual_days = relation.other_issue(self).total('done_ratio') ? (planned_days * relation.other_issue(self).total('done_ratio') / 100).floor : 0
+ @total_planned_days += planned_days
+ @total_actual_days += actual_days
+ @total_done_ratio = @total_planned_days != 0 ? (@total_actual_days * 100 / @total_planned_days).floor : 0
+ elsif type == 'max_id'
+ if othertotal && eval("@total_#{filed}.id") < othertotal.id
+ eval("@total_#{filed} = othertotal")
+ end
+ elsif type == 'min_id'
+ if othertotal && eval("@total_#{filed}.id") > othertotal.id
+ eval("@total_#{filed} = othertotal")
+ end
+ elsif type == 'sum'
+ if othertotal
+ eval("@total_#{filed} += othertotal")
+ end
+ elsif type == 'max'
+ if othertotal && eval("@total_#{filed}") < othertotal
+ eval("@total_#{filed} = othertotal")
+ end
+ elsif type == 'min'
+ if othertotal && eval("@total_#{filed}") > othertotal
+ eval("@total_#{filed} = othertotal")
+ end
+ end
+ end
+ end
+ end
+ eval("@total_#{filed}")
+ end
+
+ def childs
+ childs = []
+ relations_to.each do |relation|
+ if relation.relation_type == IssueRelation::TYPE_PARENTS
+ childs << relation.other_issue(self)
+ end
+ end
+ childs
+ end
+
+ def parents
+ parents = []
+ relations_from.each do |relation|
+ if relation.relation_type == IssueRelation::TYPE_PARENTS
+ parents << relation.other_issue(self)
+ end
+ end
+ parents
+ end
+
+ def outline_level(outline_level=0)
+
+ @outline_level = outline_level if outline_level != 0
+ @outline_level ? @outline_level : 1
+ end
+
+ def edge(edge=false)
+ @edge = edge if edge
+ @edge ? @edge : false
+ end
end
Index: app/models/issue_relation.rb
===================================================================
--- app/models/issue_relation.rb (revision 1182)
+++ app/models/issue_relation.rb (working copy)
@@ -23,11 +23,13 @@
TYPE_DUPLICATES = "duplicates"
TYPE_BLOCKS = "blocks"
TYPE_PRECEDES = "precedes"
+ TYPE_PARENTS = "parents"
TYPES = { TYPE_RELATES => { :name => :label_relates_to, :sym_name => :label_relates_to, :order => 1 },
TYPE_DUPLICATES => { :name => :label_duplicates, :sym_name => :label_duplicates, :order => 2 },
TYPE_BLOCKS => { :name => :label_blocks, :sym_name => :label_blocked_by, :order => 3 },
TYPE_PRECEDES => { :name => :label_precedes, :sym_name => :label_follows, :order => 4 },
+ TYPE_PARENTS => { :name => :label_parents, :sym_name => :label_children, :order => 5 },
}.freeze
validates_presence_of :issue_from, :issue_to, :relation_type
Index: app/controllers/projects_controller.rb
===================================================================
--- app/controllers/projects_controller.rb (revision 1182)
+++ app/controllers/projects_controller.rb (working copy)
@@ -368,6 +368,23 @@
end
@events += @project.versions.find(:all, :conditions => ["effective_date BETWEEN ? AND ?", @date_from, @date_to])
@events.sort! {|x,y| x.start_date <=> y.start_date }
+
+ parent_ids = []
+ my_ids = []
+ @events.each do |i|
+ my_ids << i.id
+ while i.parents && (i.parents.size > 0)
+ @selected_tracker_ids.each do |tracker_id|
+ parent_ids |= [i.parents[0].id] if tracker_id.to_i == i.parents[0].tracker_id
+ end
+ i = i.parents[0]
+ end
+ end
+ parent_ids.sort
+ my_ids.sort
+ parent_ids = parent_ids - my_ids
+ @events += Issue.find(:all, :include => [:tracker, :status, :assigned_to, :priority, :project], :conditions => ["#{Issue.table_name}.id in (#{parent_ids.join(',')}) and #{Issue.table_name}.tracker_id in (#{@selected_tracker_ids.join(',')})"]) unless @selected_tracker_ids.empty? || parent_ids.empty?
+ @events = issues_to_outlines(@events)
if params[:format]=='pdf'
@options_for_rfpdf ||= {}
Index: app/views/projects/gantt.rhtml
===================================================================
--- app/views/projects/gantt.rhtml (revision 1182)
+++ app/views/projects/gantt.rhtml (working copy)
@@ -70,6 +70,12 @@
@events.each do |i| %>
<% if i.is_a? Issue %>
+ <% indent = "" %>
+ <% (2).upto(i.outline_level) do |j| %>
+ <% indent += image_tag('white.png') %>
+ <% end %>
+ <% indent += (i.edge ? image_tag('white.png'):image_tag('expanded.png')) %>
+ <%= indent %>
<%= h("#{i.project.name} -") unless @project && @project == i.project %>
<%= link_to_issue i %>: <%=h i.subject %>
<% else %>
@@ -126,8 +132,8 @@
width = (week_f + 6 <= @date_to) ? 7 * zoom -1 : (@date_to - week_f + 1) * zoom-1
%>
- <%= week_f.cweek if width >= 16 %>
-
+ <% week_f.cweek if width >= 16 %><%= week_f.day if width >= 16 %>
+
<%
left = left + width+1
week_f = week_f+7
@@ -162,10 +168,10 @@
top = headers_height + 10
@events.each do |i|
if i.is_a? Issue
- i_start_date = (i.start_date >= @date_from ? i.start_date : @date_from )
- i_end_date = (i.due_date <= @date_to ? i.due_date : @date_to )
+ i_start_date = (i.total('start_date') >= @date_from ? i.total('start_date') : @date_from )
+ i_end_date = (i.total('due_date') <= @date_to ? i.total('due_date') : @date_to )
- i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
+ i_done_date = i.total('start_date') + i.total('actual_days')
i_done_date = (i_done_date <= @date_from ? @date_from : i_done_date )
i_done_date = (i_done_date >= @date_to ? @date_to : i_done_date )
@@ -184,8 +190,8 @@
<% end %>
- <%= i.status.name %>
- <%= (i.done_ratio).to_i %>%
+ <%= i.total('status').name %>
+ <%= (i.total('done_ratio')).to_i %>%
<% # === tooltip === %>
@@ -193,7 +199,7 @@
<%= render_issue_tooltip i %>
<% else
- i_left = ((i.start_date - @date_from)*zoom).floor
+ i_left = ((i.total('start_date') - @date_from)*zoom).floor
%>
Index: app/views/projects/gantt.rfpdf
===================================================================
--- app/views/projects/gantt.rfpdf (revision 1182)
+++ app/views/projects/gantt.rfpdf (working copy)
@@ -4,11 +4,6 @@
pdf.AliasNbPages
pdf.footer_date = format_date(Date.today)
pdf.AddPage("L")
-pdf.SetFontStyle('B',12)
-pdf.SetX(15)
-pdf.Cell(70, 20, @project.name)
-pdf.Ln
-pdf.SetFontStyle('B',9)
subject_width = 70
header_heigth = 5
@@ -31,9 +26,18 @@
g_height = 120
t_height = g_height + headers_heigth
+top = 20
+@events.each do |i|
+
+if (top == 20)
+pdf.SetFontStyle('B',12)
+pdf.SetX(15)
+pdf.Cell(70, 20, @project.name)
+pdf.Ln
+pdf.SetFontStyle('B',9)
+
y_start = pdf.GetY
-
#
# Months headers
#
@@ -71,7 +75,8 @@
width = (week_f + 6 <= @date_to) ? 7 * zoom : (@date_to - week_f + 1) * zoom
pdf.SetY(y_start + header_heigth)
pdf.SetX(left)
- pdf.Cell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
+# pdf.Cell(width, height, (width >= 5 ? week_f.cweek.to_s : ""), "LTR", 0, "C")
+ pdf.Cell(width, height, (width >= 5 ? week_f.day.to_s : ""), "LTR", 0, "C")
left = left + width
week_f = week_f+7
end
@@ -100,18 +105,22 @@
pdf.SetX(15)
pdf.Cell(subject_width+g_width-15, headers_heigth, "", 1)
+top = headers_heigth + y_start
+end
#
# Tasks
#
-top = headers_heigth + y_start
pdf.SetFontStyle('B',7)
-@events.each do |i|
pdf.SetY(top)
pdf.SetX(15)
if i.is_a? Issue
- pdf.Cell(subject_width-15, 5, "#{i.tracker.name} #{i.id}: #{i.subject}".sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)'), "LR")
+ pdf.Image('public/images/expanded.png', pdf.GetX+3*(i.outline_level-1)+0.5, pdf.GetY+1, 3, 3) unless i.edge
+ pdf.Cell(3*i.outline_level+1,5,'',0)
+ pdf.Cell(subject_width-15-(3*i.outline_level+1), 5, "#{i.tracker.name} #{i.id}: #{i.subject}".sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)'), 0)
+ pdf.SetX(15)
+ pdf.Cell(subject_width-15, 5, '', "LR")
else
pdf.Cell(subject_width-15, 5, "#{l(:label_version)}: #{i.name}", "LR")
end
@@ -123,10 +132,10 @@
pdf.SetY(top+1.5)
if i.is_a? Issue
- i_start_date = (i.start_date >= @date_from ? i.start_date : @date_from )
- i_end_date = (i.due_date <= @date_to ? i.due_date : @date_to )
+ i_start_date = (i.total('start_date') >= @date_from ? i.total('start_date') : @date_from )
+ i_end_date = (i.total('due_date') <= @date_to ? i.total('due_date') : @date_to )
- i_done_date = i.start_date + ((i.due_date - i.start_date+1)*i.done_ratio/100).floor
+ i_done_date = i.total('start_date') + i.total('actual_days')
i_done_date = (i_done_date <= @date_from ? @date_from : i_done_date )
i_done_date = (i_done_date >= @date_to ? @date_to : i_done_date )
@@ -157,9 +166,9 @@
pdf.SetY(top+1.5)
pdf.SetX(subject_width + i_left + i_width)
- pdf.Cell(30, 2, "#{i.status.name} #{i.done_ratio}%")
+ pdf.Cell(30, 2, "#{i.total('status').name} #{i.total('done_ratio')}%")
else
- i_left = ((i.start_date - @date_from)*zoom)
+ i_left = ((i.total('start_date') - @date_from)*zoom)
pdf.SetX(subject_width + i_left)
pdf.SetFillColor(50,200,50)
@@ -175,9 +184,10 @@
pdf.SetDrawColor(200, 200, 200)
pdf.Line(15, top, subject_width+g_width, top)
if pdf.GetY() > 180
+ pdf.SetDrawColor(0, 0, 0)
+ pdf.Line(15, top, subject_width+g_width, top)
pdf.AddPage("L")
top = 20
- pdf.Line(15, top, subject_width+g_width, top)
end
pdf.SetDrawColor(0, 0, 0)
end
Index: app/views/issues/_relations.rhtml
===================================================================
--- app/views/issues/_relations.rhtml (revision 1182)
+++ app/views/issues/_relations.rhtml (working copy)
@@ -12,9 +12,9 @@
<%= l(relation.label_for(@issue)) %> <%= "(#{lwr(:actionview_datehelper_time_in_words_day, relation.delay)})" if relation.delay && relation.delay != 0 %> <%= link_to_issue relation.other_issue(@issue) %> |
<%=h relation.other_issue(@issue).subject %> |
-<%= relation.other_issue(@issue).status.name %> |
-<%= format_date(relation.other_issue(@issue).start_date) %> |
-<%= format_date(relation.other_issue(@issue).due_date) %> |
+<%= relation.other_issue(@issue).total('status').name %> |
+<%= format_date(relation.other_issue(@issue).total('start_date')) %> |
+<%= format_date(relation.other_issue(@issue).total('due_date')) %> |
<%= link_to_remote(image_tag('delete.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :issue_id => @issue, :id => relation},
:method => :post
}, :title => l(:label_relation_delete)) if authorize_for('issue_relations', 'destroy') %> |
Index: app/views/issues/show.rhtml
===================================================================
--- app/views/issues/show.rhtml (revision 1182)
+++ app/views/issues/show.rhtml (working copy)
@@ -18,28 +18,28 @@
- <%=l(:field_status)%> : | <%= @issue.status.name %> |
- <%=l(:field_start_date)%> : | <%= format_date(@issue.start_date) %> |
+ <%=l(:field_status)%> : | <%= @issue.total('status').name %> |
+ <%=l(:field_start_date)%> : | <%= format_date(@issue.total('start_date')) %> |
- <%=l(:field_priority)%> : | <%= @issue.priority.name %> |
- <%=l(:field_due_date)%> : | <%= format_date(@issue.due_date) %> |
+ <%=l(:field_priority)%> : | <%= @issue.total('priority').name %> |
+ <%=l(:field_due_date)%> : | <%= format_date(@issue.total('due_date')) %> |
<%=l(:field_assigned_to)%> : | <%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %> |
- <%=l(:field_done_ratio)%> : | <%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %> |
+ <%=l(:field_done_ratio)%> : | <%= progress_bar @issue.total('done_ratio'), :width => '80px', :legend => "#{@issue.total('done_ratio')}%" %> |
<%=l(:field_category)%> : | <%=h @issue.category ? @issue.category.name : "-" %> |
<% if User.current.allowed_to?(:view_time_entries, @project) %>
<%=l(:label_spent_time)%> : |
- <%= @issue.spent_hours > 0 ? (link_to lwr(:label_f_hour, @issue.spent_hours), {:controller => 'timelog', :action => 'details', :issue_id => @issue}, :class => 'icon icon-time') : "-" %> |
+ <%= @issue.total('spent_hours') > 0 ? (link_to lwr(:label_f_hour, @issue.total('spent_hours')), {:controller => 'timelog', :action => 'details', :issue_id => @issue}, :class => 'icon icon-time') : "-" %> |
<% end %>
<%=l(:field_fixed_version)%> : | <%= @issue.fixed_version ? link_to_version(@issue.fixed_version) : "-" %> |
- <% if @issue.estimated_hours %>
- <%=l(:field_estimated_hours)%> : | <%= lwr(:label_f_hour, @issue.estimated_hours) %> |
+ <% if @issue.total('estimated_hours') %>
+ <%=l(:field_estimated_hours)%> : | <%= lwr(:label_f_hour, @issue.total('estimated_hours')) %> |
<% end %>
Index: app/views/issues/index.rfpdf
===================================================================
--- app/views/issues/index.rfpdf (revision 1182)
+++ app/views/issues/index.rfpdf (working copy)
@@ -5,8 +5,13 @@
pdf.footer_date = format_date(Date.today)
pdf.AddPage("L")
row_height = 7
-
- #
+
+ @issues = issues_to_outlines(@issues)
+
+ @issues.each do |issue|
+
+ if pdf.GetY() < 20
+ #
# title
#
pdf.SetFontStyle('B',11)
@@ -18,7 +23,7 @@
#
pdf.SetFontStyle('B',10)
pdf.SetFillColor(230, 230, 230)
- pdf.Cell(15, row_height, "#", 0, 0, 'L', 1)
+ pdf.Cell(15, row_height, "#", 0, 0, 'R', 1)
pdf.Cell(30, row_height, l(:field_tracker), 0, 0, 'L', 1)
pdf.Cell(30, row_height, l(:field_status), 0, 0, 'L', 1)
pdf.Cell(30, row_height, l(:field_priority), 0, 0, 'L', 1)
@@ -29,22 +34,28 @@
pdf.Ln
pdf.Line(10, pdf.GetY, 287, pdf.GetY)
pdf.SetY(pdf.GetY() + 1)
+ end
#
# rows
#
pdf.SetFontStyle('',9)
pdf.SetFillColor(255, 255, 255)
- @issues.each do |issue|
- pdf.Cell(15, row_height, issue.id.to_s, 0, 0, 'L', 1)
+ pdf.Cell(15, row_height, issue.id.to_s, 0, 0, 'R', 1)
pdf.Cell(30, row_height, issue.tracker.name, 0, 0, 'L', 1)
- pdf.Cell(30, row_height, issue.status.name, 0, 0, 'L', 1)
- pdf.Cell(30, row_height, issue.priority.name, 0, 0, 'L', 1)
+ pdf.Cell(30, row_height, issue.total('status').name, 0, 0, 'L', 1)
+ pdf.Cell(30, row_height, issue.total('priority').name, 0, 0, 'L', 1)
pdf.Cell(40, row_height, issue.assigned_to ? issue.assigned_to.name : '', 0, 0, 'L', 1)
pdf.Cell(25, row_height, format_date(issue.updated_on), 0, 0, 'L', 1)
+ pdf.Image('public/images/expanded.png', pdf.GetX+3*(issue.outline_level-1)+0.5, pdf.GetY+2, 3, 3) unless issue.edge
+ pdf.Cell(3*issue.outline_level+1,row_height,'',0)
pdf.MultiCell(0, row_height, (@project == issue.project ? issue.subject : "#{issue.project.name} - #{issue.subject}"))
pdf.Line(10, pdf.GetY, 287, pdf.GetY)
pdf.SetY(pdf.GetY() + 1)
+
+ if pdf.GetY() > 180
+ pdf.AddPage("L")
end
+ end
%>
<%= pdf.Output %>
\ No newline at end of file
Index: app/views/issues/_pdf.rfpdf
===================================================================
--- app/views/issues/_pdf.rfpdf (revision 1182)
+++ app/views/issues/_pdf.rfpdf (working copy)
@@ -7,11 +7,11 @@
pdf.SetFontStyle('B',9)
pdf.Cell(35,5, l(:field_status) + ":","LT")
pdf.SetFontStyle('',9)
- pdf.Cell(60,5, issue.status.name,"RT")
+ pdf.Cell(60,5, issue.total('status').name,"RT")
pdf.SetFontStyle('B',9)
pdf.Cell(35,5, l(:field_priority) + ":","LT")
pdf.SetFontStyle('',9)
- pdf.Cell(60,5, issue.priority.name,"RT")
+ pdf.Cell(60,5, issue.total('priority').name,"RT")
pdf.Ln
pdf.SetFontStyle('B',9)
@@ -41,7 +41,7 @@
pdf.SetFontStyle('B',9)
pdf.Cell(35,5, l(:field_due_date) + ":","LB")
pdf.SetFontStyle('',9)
- pdf.Cell(60,5, format_date(issue.due_date),"RB")
+ pdf.Cell(60,5, format_date(issue.total('due_date')),"RB")
pdf.Ln
for custom_value in issue.custom_values
Index: lang/uk.yml
===================================================================
--- lang/uk.yml (revision 1182)
+++ lang/uk.yml (working copy)
@@ -122,6 +122,7 @@
field_due_date: Дата виконання
field_assigned_to: Призначена до
field_priority: Пріоритет
+field_outline: Outline
field_fixed_version: Фіксована версія
field_user: Користувач
field_role: Роль
@@ -411,6 +412,8 @@
label_blocked_by: заблоковане
label_precedes: передує
label_follows: наступний за
+label_parents: parents
+label_children: children
label_end_to_start: з кінця до початку
label_end_to_end: з кінця до кінця
label_start_to_start: з початку до початку
Index: lang/lt.yml
===================================================================
--- lang/lt.yml (revision 1182)
+++ lang/lt.yml (working copy)
@@ -125,6 +125,7 @@
field_due_date: Užbaigimo data
field_assigned_to: Paskirtas
field_priority: Prioritetas
+field_outline: Outline
field_fixed_version: Pastovi versija
field_user: Vartotojas
field_role: Vaidmuo
@@ -414,6 +415,8 @@
label_blocked_by: blokuotas
label_precedes: įvyksta pirma
label_follows: seka
+label_parents: parents
+label_children: children
label_end_to_start: užbaigti, kad pradėti
label_end_to_end: užbaigti, kad pabaigti
label_start_to_start: pradėkite pradėti
Index: lang/ro.yml
===================================================================
--- lang/ro.yml (revision 1182)
+++ lang/ro.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Data finalizarii
field_assigned_to: Atribuit pentru
field_priority: Prioritate
+field_outline: Outline
field_fixed_version: Versiune rezolvata
field_user: Utilizator
field_role: Rol
@@ -393,6 +394,8 @@
label_blocked_by: blocat de
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: de la sfarsit la capat
label_end_to_end: de la sfarsit la sfarsit
label_start_to_start: de la capat la capat
Index: lang/zh.yml
===================================================================
--- lang/zh.yml (revision 1182)
+++ lang/zh.yml (working copy)
@@ -120,6 +120,7 @@
field_due_date: 到期日
field_assigned_to: 指派
field_priority: 优先级
+field_outline: Outline
field_fixed_version: 修订版本
field_user: 用户
field_role: 角色
@@ -397,6 +398,8 @@
label_blocked_by: blocked by
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/pt.yml
===================================================================
--- lang/pt.yml (revision 1182)
+++ lang/pt.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Data final
field_assigned_to: Atribuído para
field_priority: Prioridade
+field_outline: Outline
field_fixed_version: Versão corrigida
field_user: Usuário
field_role: Regra
@@ -395,6 +396,8 @@
label_blocked_by: bloqueado por
label_precedes: procede
label_follows: segue
+label_parents: parents
+label_children: children
label_end_to_start: fim ao início
label_end_to_end: fim ao fim
label_start_to_start: ínícia ao inícia
Index: lang/sr.yml
===================================================================
--- lang/sr.yml (revision 1182)
+++ lang/sr.yml (working copy)
@@ -121,6 +121,7 @@
field_due_date: Do datuma
field_assigned_to: Dodeljeno
field_priority: Prioritet
+field_outline: Outline
field_fixed_version: Ispravljena verzija
field_user: Korisnik
field_role: Uloga
@@ -405,6 +406,8 @@
label_blocked_by: blokiran od strane
label_precedes: prethodi
label_follows: sledi
+label_parents: parents
+label_children: children
label_end_to_start: od kraja do početka
label_end_to_end: od kraja do kraja
label_start_to_start: od početka do pocetka
Index: lang/pt-br.yml
===================================================================
--- lang/pt-br.yml (revision 1182)
+++ lang/pt-br.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Data devida
field_assigned_to: Atribuido para
field_priority: Prioridade
+field_outline: Outline
field_fixed_version: Versao corrigida
field_user: Usuario
field_role: Regra
@@ -395,6 +396,8 @@
label_blocked_by: blocked by
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/ru.yml
===================================================================
--- lang/ru.yml (revision 1182)
+++ lang/ru.yml (working copy)
@@ -127,6 +127,7 @@
field_due_date: Дата выполнения
field_assigned_to: Назначена
field_priority: Приоритет
+field_outline: Outline
field_fixed_version: Фиксированная версия
field_user: Пользователь
field_role: Роль
@@ -418,6 +419,8 @@
label_blocked_by: заблокировано
label_precedes: предшествует
label_follows: следующий
+label_parents: parents
+label_children: children
label_end_to_start: с конца к началу
label_end_to_end: с конца к концу
label_start_to_start: с начала к началу
Index: lang/sv.yml
===================================================================
--- lang/sv.yml (revision 1182)
+++ lang/sv.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Färdigdatum
field_assigned_to: Tilldelad
field_priority: Prioritet
+field_outline: Outline
field_fixed_version: Fixed version
field_user: Användare
field_role: Roll
@@ -395,6 +396,8 @@
label_blocked_by: blocked by
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/bg.yml
===================================================================
--- lang/bg.yml (revision 1182)
+++ lang/bg.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Крайна дата
field_assigned_to: Възложена на
field_priority: Приоритет
+field_outline: Outline
field_fixed_version: Версия
field_user: Потребител
field_role: Роля
@@ -395,6 +396,8 @@
label_blocked_by: блокирана от
label_precedes: предшества
label_follows: изпълнява се след
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/de.yml
===================================================================
--- lang/de.yml (revision 1182)
+++ lang/de.yml (working copy)
@@ -126,6 +126,7 @@
field_due_date: Abgabedatum
field_assigned_to: Zugewiesen an
field_priority: Priorität
+field_outline: Outline
field_fixed_version: Erledigt in Version
field_user: Benutzer
field_role: Rolle
@@ -420,6 +421,8 @@
label_blocked_by: Blockiert durch
label_precedes: Vorgänger von
label_follows: folgt
+label_parents: parents
+label_children: children
label_end_to_start: Ende - Anfang
label_end_to_end: Ende - Ende
label_start_to_start: Anfang - Anfang
Index: lang/ja.yml
===================================================================
--- lang/ja.yml (revision 1182)
+++ lang/ja.yml (working copy)
@@ -118,6 +118,7 @@
field_due_date: 期限日
field_assigned_to: 担当者
field_priority: 優先度
+field_outline: アウトライン
field_fixed_version: 修正されたバージョン
field_user: ユーザ
field_role: 役割
@@ -396,6 +397,8 @@
label_blocked_by: ブロックされている
label_precedes: 先行する
label_follows: 後続する
+label_parents: 親
+label_children: 子
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/he.yml
===================================================================
--- lang/he.yml (revision 1182)
+++ lang/he.yml (working copy)
@@ -119,6 +119,7 @@
field_due_date: תאריך סיום
field_assigned_to: מוצב ל
field_priority: עדיפות
+field_outline: Outline
field_fixed_version: גירסא מקובעת
field_user: מתשמש
field_role: תפקיד
@@ -400,6 +401,8 @@
label_blocked_by: חסום ע"י
label_precedes: מקדים את
label_follows: עוקב אחרי
+label_parents: parents
+label_children: children
label_end_to_start: מהתחלה לסוף
label_end_to_end: מהסוף לסוף
label_start_to_start: מהתחלה להתחלה
Index: lang/fi.yml
===================================================================
--- lang/fi.yml (revision 1182)
+++ lang/fi.yml (working copy)
@@ -126,6 +126,7 @@
field_due_date: Määräaika
field_assigned_to: Nimetty
field_priority: Prioriteetti
+field_outline: Outline
field_fixed_version: Määrätty versio
field_user: Käyttäjä
field_role: Rooli
@@ -418,6 +419,8 @@
label_blocked_by: estetty
label_precedes: edeltää
label_follows: seuraa
+label_parents: parents
+label_children: children
label_end_to_start: loppu alkuun
label_end_to_end: loppu loppuun
label_start_to_start: alku alkuun
Index: lang/en.yml
===================================================================
--- lang/en.yml (revision 1182)
+++ lang/en.yml (working copy)
@@ -127,6 +127,7 @@
field_due_date: Due date
field_assigned_to: Assigned to
field_priority: Priority
+field_outline: Outline
field_fixed_version: Fixed version
field_user: User
field_role: Role
@@ -443,6 +444,8 @@
label_blocked_by: blocked by
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/cs.yml
===================================================================
--- lang/cs.yml (revision 1182)
+++ lang/cs.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Po lhůtě
field_assigned_to: Přiřazeno
field_priority: Priorita
+field_outline: Outline
field_fixed_version: Pevná verze
field_user: Uživatel
field_role: Role
@@ -393,6 +394,8 @@
label_blocked_by: zamčeno
label_precedes: předchází
label_follows: následuje
+label_parents: parents
+label_children: children
label_end_to_start: od konce do začátku
label_end_to_end: od konce do konce
label_start_to_start: od začátku do začátku
Index: lang/fr.yml
===================================================================
--- lang/fr.yml (revision 1182)
+++ lang/fr.yml (working copy)
@@ -127,6 +127,7 @@
field_due_date: Date d'échéance
field_assigned_to: Assigné à
field_priority: Priorité
+field_outline: Outline
field_fixed_version: Version corrigée
field_user: Utilisateur
field_role: Rôle
@@ -443,6 +444,8 @@
label_blocked_by: bloqué par
label_precedes: précède
label_follows: suit
+label_parents: parents
+label_children: children
label_end_to_start: fin à début
label_end_to_end: fin à fin
label_start_to_start: début à début
Index: lang/es.yml
===================================================================
--- lang/es.yml (revision 1182)
+++ lang/es.yml (working copy)
@@ -114,6 +114,7 @@
field_due_date: Fecha fin
field_assigned_to: Asignado a
field_priority: Prioridad
+field_outline: Outline
field_fixed_version: Versión
field_user: Usuario
field_role: Perfil
@@ -386,6 +387,8 @@
label_blocked_by: bloqueado por
label_precedes: anterior a
label_follows: posterior a
+label_parents: parents
+label_children: children
label_end_to_start: fin a principio
label_end_to_end: fin a fin
label_start_to_start: principio a principio
Index: lang/nl.yml
===================================================================
--- lang/nl.yml (revision 1182)
+++ lang/nl.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Verwachte datum gereed
field_assigned_to: Toegewezen aan
field_priority: Prioriteit
+field_outline: Outline
field_fixed_version: Opgeloste versie
field_user: Gebruiker
field_role: Rol
@@ -395,6 +396,8 @@
label_blocked_by: geblokkeerd door
label_precedes: gaat vooraf aan
label_follows: volgt op
+label_parents: parents
+label_children: children
label_end_to_start: eind tot start
label_end_to_end: eind tot eind
label_start_to_start: start tot start
Index: lang/ko.yml
===================================================================
--- lang/ko.yml (revision 1182)
+++ lang/ko.yml (working copy)
@@ -119,6 +119,7 @@
field_due_date: 완료 기한
field_assigned_to: 담당자
field_priority: 우선순위
+field_outline: Outline
field_fixed_version: 마일스톤
field_user: 유저
field_role: 역할
@@ -402,6 +403,8 @@
label_blocked_by: 막고 있는 티켓
label_precedes: 다음 티켓보다 앞서서 처리해야 함.
label_follows: 선처리티켓
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/zh-tw.yml
===================================================================
--- lang/zh-tw.yml (revision 1182)
+++ lang/zh-tw.yml (working copy)
@@ -126,6 +126,7 @@
field_due_date: 完成日期
field_assigned_to: 分派給
field_priority: 優先權
+field_outline: Outline
field_fixed_version: 版本
field_user: 用戶
field_role: 角色
@@ -425,6 +426,8 @@
label_blocked_by: 被阻擋
label_precedes: 優先於
label_follows: 跟隨於
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start
Index: lang/pl.yml
===================================================================
--- lang/pl.yml (revision 1182)
+++ lang/pl.yml (working copy)
@@ -114,6 +114,7 @@
field_due_date: Data oddania
field_assigned_to: Przydzielony do
field_priority: Priorytet
+field_outline: Outline
field_fixed_version: Wersja
field_user: Użytkownik
field_role: Rola
@@ -386,6 +387,8 @@
label_blocked_by: zablokowane przez
label_precedes: poprzedza
label_follows: podąża
+label_parents: parents
+label_children: children
label_end_to_start: koniec do początku
label_end_to_end: koniec do końca
label_start_to_start: początek do początku
Index: lang/it.yml
===================================================================
--- lang/it.yml (revision 1182)
+++ lang/it.yml (working copy)
@@ -117,6 +117,7 @@
field_due_date: Data ultima
field_assigned_to: Assegnato a
field_priority: Priorita'
+field_outline: Outline
field_fixed_version: Versione di fix
field_user: Utente
field_role: Ruolo
@@ -395,6 +396,8 @@
label_blocked_by: blocked by
label_precedes: precedes
label_follows: follows
+label_parents: parents
+label_children: children
label_end_to_start: end to start
label_end_to_end: end to end
label_start_to_start: start to start