Feature #37362 » feature-37362.patch
app/controllers/reports_controller.rb | ||
---|---|---|
21 | 21 |
menu_item :issues |
22 | 22 |
before_action :find_project, :authorize, :find_issue_statuses |
23 | 23 | |
24 |
include ReportsHelper |
|
24 | 25 |
def issue_report |
25 | 26 |
with_subprojects = Setting.display_subprojects_issues? |
26 | 27 |
@trackers = @project.rolled_up_trackers(with_subprojects).visible |
... | ... | |
82 | 83 |
else |
83 | 84 |
render_404 |
84 | 85 |
end |
86 |
respond_to do |format| |
|
87 |
format.html |
|
88 |
format.csv do |
|
89 |
send_data(issue_report_details_to_csv(@field, @statuses, @rows, @data), :type => 'text/csv; header=present', :filename => "report-#{params[:detail]}.csv") |
|
90 |
end |
|
91 |
end |
|
85 | 92 |
end |
86 | 93 | |
87 | 94 |
private |
app/helpers/reports_helper.rb | ||
---|---|---|
44 | 44 |
parameters = {:set_filter => 1, :subproject_id => '!*', field => (row.id || '!*')}.merge(options) |
45 | 45 |
project_issues_path(row.is_a?(Project) ? row : project, parameters) |
46 | 46 |
end |
47 | ||
48 |
def issue_report_details_to_csv(field_name, statuses, rows, data) |
|
49 |
Redmine::Export::CSV.generate(:encoding => params[:encoding]) do |csv| |
|
50 |
# csv headers |
|
51 |
headers = [''] + statuses.map(&:name) + [l(:label_open_issues_plural), l(:label_closed_issues_plural), l(:label_total)] |
|
52 |
csv << headers |
|
53 | ||
54 |
# csv lines |
|
55 |
rows.each do |row| |
|
56 |
csv << |
|
57 |
[row.name] + |
|
58 |
statuses.map{|s| aggregate(data, { field_name => row.id, "status_id" => s.id })} + |
|
59 |
[aggregate(data, { field_name => row.id, "closed" => 0 })] + |
|
60 |
[aggregate(data, { field_name => row.id, "closed" => 1 })] + |
|
61 |
[aggregate(data, { field_name => row.id })] |
|
62 |
end |
|
63 |
end |
|
64 |
end |
|
47 | 65 |
end |
app/views/reports/_details.html.erb | ||
---|---|---|
25 | 25 |
<% end %> |
26 | 26 |
</tbody> |
27 | 27 |
</table> |
28 |
<% other_formats_links do |f| %> |
|
29 |
<%= f.link_to_with_query_parameters 'CSV', {}, :onclick => "showModal('csv-export-options', '330px'); return false;" %> |
|
30 |
<% end %> |
|
31 |
<div id="csv-export-options" style="display: none;"> |
|
32 |
<h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3> |
|
33 |
<%= form_tag(project_issues_report_details_path(@project, :detail => params[:detail], :format => 'csv'), :method => :get, :id => 'csv-export-form') do %> |
|
34 |
<%= export_csv_encoding_select_tag %> |
|
35 |
<p class="buttons"> |
|
36 |
<%= submit_tag l(:button_export), :name => nil, :onclick => 'hideModal(this);', :data => {:disable_with => false} %> |
|
37 |
<%= link_to_function l(:button_cancel), 'hideModal(this);' %> |
|
38 |
</p> |
|
39 |
<% end %> |
|
40 |
</div> |
|
41 | ||
28 | 42 |
<div class="issue-report-graph hide-when-print"> |
29 | 43 |
<canvas id="issues_by_<%= params[:detail] %>"></canvas> |
30 | 44 |
</div> |
test/functional/reports_controller_test.rb | ||
---|---|---|
242 | 242 |
) |
243 | 243 |
assert_response 404 |
244 | 244 |
end |
245 | ||
246 |
def test_issue_report_details_should_csv_export |
|
247 |
%w(tracker version priority category assigned_to author subproject).each do |detail| |
|
248 |
get( |
|
249 |
:issue_report_details, |
|
250 |
params: { |
|
251 |
id: 1, |
|
252 |
detail: detail, |
|
253 |
format: 'csv' |
|
254 |
} |
|
255 |
) |
|
256 |
assert_response :success |
|
257 |
assert_equal 'text/csv; header=present', response.media_type |
|
258 |
end |
|
259 |
end |
|
260 | ||
261 |
def test_issue_report_details_with_tracker_detail_should_csv_export |
|
262 |
project = Project.find(1) |
|
263 |
tracker = project.trackers.find_by(:name => 'Support request') |
|
264 |
project.trackers.delete(tracker) |
|
265 | ||
266 |
with_settings :display_subprojects_issues => '1' do |
|
267 |
get( |
|
268 |
:issue_report_details, |
|
269 |
params: { |
|
270 |
id: 1, |
|
271 |
detail: 'tracker', |
|
272 |
format: 'csv' |
|
273 |
} |
|
274 |
) |
|
275 |
assert_response :success |
|
276 | ||
277 |
assert_equal 'text/csv; header=present', response.media_type |
|
278 |
lines = response.body.chomp.split("\n") |
|
279 |
# Number of lines |
|
280 |
rows = Project.find(1).rolled_up_trackers(true).visible |
|
281 |
assert_equal rows.size + 1, lines.size |
|
282 |
# Header |
|
283 |
assert_equal "\"\",New,Assigned,Resolved,Feedback,Closed,Rejected,open,closed,Total", lines.first |
|
284 |
# Details |
|
285 |
to_test = [ |
|
286 |
'Bug,5,0,0,0,3,0,5,3,8', |
|
287 |
'Feature request,0,1,0,0,0,0,1,0,1', |
|
288 |
'Support request,0,0,0,0,0,0,0,0,0' |
|
289 |
] |
|
290 |
to_test.each do |expected| |
|
291 |
assert_includes lines, expected |
|
292 |
end |
|
293 |
end |
|
294 |
end |
|
295 | ||
296 |
def test_issue_report_details_with_assigned_to_detail_should_csv_export |
|
297 |
Issue.delete_all |
|
298 |
Issue.generate! |
|
299 |
Issue.generate! |
|
300 |
Issue.generate!(:status_id => 5) |
|
301 |
Issue.generate!(:assigned_to_id => 2) |
|
302 | ||
303 |
with_settings :issue_group_assignment => '1' do |
|
304 |
get( |
|
305 |
:issue_report_details, |
|
306 |
params: { |
|
307 |
id: 1, |
|
308 |
detail: 'assigned_to', |
|
309 |
format: 'csv' |
|
310 |
} |
|
311 |
) |
|
312 |
assert_response :success |
|
313 | ||
314 |
assert_equal 'text/csv; header=present', response.media_type |
|
315 |
lines = response.body.chomp.split("\n") |
|
316 |
# Number of lines |
|
317 |
rows = Project.find(1).principals.sorted + [I18n.t(:label_none)] |
|
318 |
assert_equal rows.size + 1, lines.size |
|
319 |
# Header |
|
320 |
assert_equal "\"\",New,Assigned,Resolved,Feedback,Closed,Rejected,open,closed,Total", lines.first |
|
321 |
# Details |
|
322 |
to_test = [ |
|
323 |
'Dave Lopper,0,0,0,0,0,0,0,0,0', |
|
324 |
'John Smith,1,0,0,0,0,0,1,0,1', |
|
325 |
'[none] ,2,0,0,0,1,0,2,1,3' |
|
326 |
] |
|
327 |
to_test.each do |expected| |
|
328 |
assert_includes lines, expected |
|
329 |
end |
|
330 |
end |
|
331 |
end |
|
245 | 332 |
end |
- « Previous
- 1
- 2
- Next »