##// END OF EJS Templates
Fixed: Estimated time in issue's journal should be rounded to two decimals (#1793)....
Jean-Philippe Lang -
r1753:5ef0af67101e
parent child
Show More
@@ -1,184 +1,187
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'csv'
18 require 'csv'
19
19
20 module IssuesHelper
20 module IssuesHelper
21 include ApplicationHelper
21 include ApplicationHelper
22
22
23 def render_issue_tooltip(issue)
23 def render_issue_tooltip(issue)
24 @cached_label_start_date ||= l(:field_start_date)
24 @cached_label_start_date ||= l(:field_start_date)
25 @cached_label_due_date ||= l(:field_due_date)
25 @cached_label_due_date ||= l(:field_due_date)
26 @cached_label_assigned_to ||= l(:field_assigned_to)
26 @cached_label_assigned_to ||= l(:field_assigned_to)
27 @cached_label_priority ||= l(:field_priority)
27 @cached_label_priority ||= l(:field_priority)
28
28
29 link_to_issue(issue) + ": #{h(issue.subject)}<br /><br />" +
29 link_to_issue(issue) + ": #{h(issue.subject)}<br /><br />" +
30 "<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" +
30 "<strong>#{@cached_label_start_date}</strong>: #{format_date(issue.start_date)}<br />" +
31 "<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" +
31 "<strong>#{@cached_label_due_date}</strong>: #{format_date(issue.due_date)}<br />" +
32 "<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" +
32 "<strong>#{@cached_label_assigned_to}</strong>: #{issue.assigned_to}<br />" +
33 "<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}"
33 "<strong>#{@cached_label_priority}</strong>: #{issue.priority.name}"
34 end
34 end
35
35
36 def sidebar_queries
36 def sidebar_queries
37 unless @sidebar_queries
37 unless @sidebar_queries
38 # User can see public queries and his own queries
38 # User can see public queries and his own queries
39 visible = ARCondition.new(["is_public = ? OR user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
39 visible = ARCondition.new(["is_public = ? OR user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
40 # Project specific queries and global queries
40 # Project specific queries and global queries
41 visible << (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
41 visible << (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id])
42 @sidebar_queries = Query.find(:all,
42 @sidebar_queries = Query.find(:all,
43 :order => "name ASC",
43 :order => "name ASC",
44 :conditions => visible.conditions)
44 :conditions => visible.conditions)
45 end
45 end
46 @sidebar_queries
46 @sidebar_queries
47 end
47 end
48
48
49 def show_detail(detail, no_html=false)
49 def show_detail(detail, no_html=false)
50 case detail.property
50 case detail.property
51 when 'attr'
51 when 'attr'
52 label = l(("field_" + detail.prop_key.to_s.gsub(/\_id$/, "")).to_sym)
52 label = l(("field_" + detail.prop_key.to_s.gsub(/\_id$/, "")).to_sym)
53 case detail.prop_key
53 case detail.prop_key
54 when 'due_date', 'start_date'
54 when 'due_date', 'start_date'
55 value = format_date(detail.value.to_date) if detail.value
55 value = format_date(detail.value.to_date) if detail.value
56 old_value = format_date(detail.old_value.to_date) if detail.old_value
56 old_value = format_date(detail.old_value.to_date) if detail.old_value
57 when 'project_id'
57 when 'project_id'
58 p = Project.find_by_id(detail.value) and value = p.name if detail.value
58 p = Project.find_by_id(detail.value) and value = p.name if detail.value
59 p = Project.find_by_id(detail.old_value) and old_value = p.name if detail.old_value
59 p = Project.find_by_id(detail.old_value) and old_value = p.name if detail.old_value
60 when 'status_id'
60 when 'status_id'
61 s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
61 s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
62 s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
62 s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
63 when 'tracker_id'
63 when 'tracker_id'
64 t = Tracker.find_by_id(detail.value) and value = t.name if detail.value
64 t = Tracker.find_by_id(detail.value) and value = t.name if detail.value
65 t = Tracker.find_by_id(detail.old_value) and old_value = t.name if detail.old_value
65 t = Tracker.find_by_id(detail.old_value) and old_value = t.name if detail.old_value
66 when 'assigned_to_id'
66 when 'assigned_to_id'
67 u = User.find_by_id(detail.value) and value = u.name if detail.value
67 u = User.find_by_id(detail.value) and value = u.name if detail.value
68 u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
68 u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
69 when 'priority_id'
69 when 'priority_id'
70 e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
70 e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
71 e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
71 e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
72 when 'category_id'
72 when 'category_id'
73 c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
73 c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
74 c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
74 c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
75 when 'fixed_version_id'
75 when 'fixed_version_id'
76 v = Version.find_by_id(detail.value) and value = v.name if detail.value
76 v = Version.find_by_id(detail.value) and value = v.name if detail.value
77 v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
77 v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
78 when 'estimated_hours'
79 value = "%0.02f" % detail.value.to_f unless detail.value.blank?
80 old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank?
78 end
81 end
79 when 'cf'
82 when 'cf'
80 custom_field = CustomField.find_by_id(detail.prop_key)
83 custom_field = CustomField.find_by_id(detail.prop_key)
81 if custom_field
84 if custom_field
82 label = custom_field.name
85 label = custom_field.name
83 value = format_value(detail.value, custom_field.field_format) if detail.value
86 value = format_value(detail.value, custom_field.field_format) if detail.value
84 old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
87 old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
85 end
88 end
86 when 'attachment'
89 when 'attachment'
87 label = l(:label_attachment)
90 label = l(:label_attachment)
88 end
91 end
89
92
90 label ||= detail.prop_key
93 label ||= detail.prop_key
91 value ||= detail.value
94 value ||= detail.value
92 old_value ||= detail.old_value
95 old_value ||= detail.old_value
93
96
94 unless no_html
97 unless no_html
95 label = content_tag('strong', label)
98 label = content_tag('strong', label)
96 old_value = content_tag("i", h(old_value)) if detail.old_value
99 old_value = content_tag("i", h(old_value)) if detail.old_value
97 old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
100 old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?)
98 if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key)
101 if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key)
99 # Link to the attachment if it has not been removed
102 # Link to the attachment if it has not been removed
100 value = link_to_attachment(a)
103 value = link_to_attachment(a)
101 else
104 else
102 value = content_tag("i", h(value)) if value
105 value = content_tag("i", h(value)) if value
103 end
106 end
104 end
107 end
105
108
106 if !detail.value.blank?
109 if !detail.value.blank?
107 case detail.property
110 case detail.property
108 when 'attr', 'cf'
111 when 'attr', 'cf'
109 if !detail.old_value.blank?
112 if !detail.old_value.blank?
110 label + " " + l(:text_journal_changed, old_value, value)
113 label + " " + l(:text_journal_changed, old_value, value)
111 else
114 else
112 label + " " + l(:text_journal_set_to, value)
115 label + " " + l(:text_journal_set_to, value)
113 end
116 end
114 when 'attachment'
117 when 'attachment'
115 "#{label} #{value} #{l(:label_added)}"
118 "#{label} #{value} #{l(:label_added)}"
116 end
119 end
117 else
120 else
118 case detail.property
121 case detail.property
119 when 'attr', 'cf'
122 when 'attr', 'cf'
120 label + " " + l(:text_journal_deleted) + " (#{old_value})"
123 label + " " + l(:text_journal_deleted) + " (#{old_value})"
121 when 'attachment'
124 when 'attachment'
122 "#{label} #{old_value} #{l(:label_deleted)}"
125 "#{label} #{old_value} #{l(:label_deleted)}"
123 end
126 end
124 end
127 end
125 end
128 end
126
129
127 def issues_to_csv(issues, project = nil)
130 def issues_to_csv(issues, project = nil)
128 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
131 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
129 decimal_separator = l(:general_csv_decimal_separator)
132 decimal_separator = l(:general_csv_decimal_separator)
130 export = StringIO.new
133 export = StringIO.new
131 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
134 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
132 # csv header fields
135 # csv header fields
133 headers = [ "#",
136 headers = [ "#",
134 l(:field_status),
137 l(:field_status),
135 l(:field_project),
138 l(:field_project),
136 l(:field_tracker),
139 l(:field_tracker),
137 l(:field_priority),
140 l(:field_priority),
138 l(:field_subject),
141 l(:field_subject),
139 l(:field_assigned_to),
142 l(:field_assigned_to),
140 l(:field_category),
143 l(:field_category),
141 l(:field_fixed_version),
144 l(:field_fixed_version),
142 l(:field_author),
145 l(:field_author),
143 l(:field_start_date),
146 l(:field_start_date),
144 l(:field_due_date),
147 l(:field_due_date),
145 l(:field_done_ratio),
148 l(:field_done_ratio),
146 l(:field_estimated_hours),
149 l(:field_estimated_hours),
147 l(:field_created_on),
150 l(:field_created_on),
148 l(:field_updated_on)
151 l(:field_updated_on)
149 ]
152 ]
150 # Export project custom fields if project is given
153 # Export project custom fields if project is given
151 # otherwise export custom fields marked as "For all projects"
154 # otherwise export custom fields marked as "For all projects"
152 custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields
155 custom_fields = project.nil? ? IssueCustomField.for_all : project.all_issue_custom_fields
153 custom_fields.each {|f| headers << f.name}
156 custom_fields.each {|f| headers << f.name}
154 # Description in the last column
157 # Description in the last column
155 headers << l(:field_description)
158 headers << l(:field_description)
156 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
159 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
157 # csv lines
160 # csv lines
158 issues.each do |issue|
161 issues.each do |issue|
159 fields = [issue.id,
162 fields = [issue.id,
160 issue.status.name,
163 issue.status.name,
161 issue.project.name,
164 issue.project.name,
162 issue.tracker.name,
165 issue.tracker.name,
163 issue.priority.name,
166 issue.priority.name,
164 issue.subject,
167 issue.subject,
165 issue.assigned_to,
168 issue.assigned_to,
166 issue.category,
169 issue.category,
167 issue.fixed_version,
170 issue.fixed_version,
168 issue.author.name,
171 issue.author.name,
169 format_date(issue.start_date),
172 format_date(issue.start_date),
170 format_date(issue.due_date),
173 format_date(issue.due_date),
171 issue.done_ratio,
174 issue.done_ratio,
172 issue.estimated_hours.to_s.gsub('.', decimal_separator),
175 issue.estimated_hours.to_s.gsub('.', decimal_separator),
173 format_time(issue.created_on),
176 format_time(issue.created_on),
174 format_time(issue.updated_on)
177 format_time(issue.updated_on)
175 ]
178 ]
176 custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) }
179 custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) }
177 fields << issue.description
180 fields << issue.description
178 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
181 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
179 end
182 end
180 end
183 end
181 export.rewind
184 export.rewind
182 export
185 export
183 end
186 end
184 end
187 end
General Comments 0
You need to be logged in to leave comments. Login now