@@ -372,7 +372,6 module IssuesHelper | |||||
372 | end |
|
372 | end | |
373 |
|
373 | |||
374 | def issues_to_csv(issues, project, query, options={}) |
|
374 | def issues_to_csv(issues, project, query, options={}) | |
375 | decimal_separator = l(:general_csv_decimal_separator) |
|
|||
376 | encoding = l(:general_csv_encoding) |
|
375 | encoding = l(:general_csv_encoding) | |
377 | columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns) |
|
376 | columns = (options[:columns] == 'all' ? query.available_inline_columns : query.inline_columns) | |
378 | if options[:description] |
|
377 | if options[:description] | |
@@ -384,28 +383,9 module IssuesHelper | |||||
384 | export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| |
|
383 | export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| | |
385 | # csv header fields |
|
384 | # csv header fields | |
386 | csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) } |
|
385 | csv << [ "#" ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(c.caption.to_s, encoding) } | |
387 |
|
||||
388 | # csv lines |
|
386 | # csv lines | |
389 | issues.each do |issue| |
|
387 | issues.each do |issue| | |
390 | col_values = columns.collect do |column| |
|
388 | csv << [ issue.id.to_s ] + columns.collect {|c| Redmine::CodesetUtil.from_utf8(csv_content(c, issue), encoding) } | |
391 | s = if column.is_a?(QueryCustomFieldColumn) |
|
|||
392 | cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id} |
|
|||
393 | show_value(cv) |
|
|||
394 | else |
|
|||
395 | value = column.value(issue) |
|
|||
396 | if value.is_a?(Date) |
|
|||
397 | format_date(value) |
|
|||
398 | elsif value.is_a?(Time) |
|
|||
399 | format_time(value) |
|
|||
400 | elsif value.is_a?(Float) |
|
|||
401 | ("%.2f" % value).gsub('.', decimal_separator) |
|
|||
402 | else |
|
|||
403 | value |
|
|||
404 | end |
|
|||
405 | end |
|
|||
406 | s.to_s |
|
|||
407 | end |
|
|||
408 | csv << [ issue.id.to_s ] + col_values.collect {|c| Redmine::CodesetUtil.from_utf8(c.to_s, encoding) } |
|
|||
409 | end |
|
389 | end | |
410 | end |
|
390 | end | |
411 | export |
|
391 | export |
@@ -96,6 +96,31 module QueriesHelper | |||||
96 | end |
|
96 | end | |
97 | end |
|
97 | end | |
98 |
|
98 | |||
|
99 | def csv_content(column, issue) | |||
|
100 | value = column.value(issue) | |||
|
101 | if value.is_a?(Array) | |||
|
102 | value.collect {|v| csv_value(column, issue, v)}.compact.join(', ') | |||
|
103 | else | |||
|
104 | csv_value(column, issue, value) | |||
|
105 | end | |||
|
106 | end | |||
|
107 | ||||
|
108 | def csv_value(column, issue, value) | |||
|
109 | case value.class.name | |||
|
110 | when 'Time' | |||
|
111 | format_time(value) | |||
|
112 | when 'Date' | |||
|
113 | format_date(value) | |||
|
114 | when 'Float' | |||
|
115 | sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator)) | |||
|
116 | when 'IssueRelation' | |||
|
117 | other = value.other_issue(issue) | |||
|
118 | l(value.label_for(issue)) + " ##{other.id}" | |||
|
119 | else | |||
|
120 | value.to_s | |||
|
121 | end | |||
|
122 | end | |||
|
123 | ||||
99 | # Retrieve query from session or build a new query |
|
124 | # Retrieve query from session or build a new query | |
100 | def retrieve_query |
|
125 | def retrieve_query | |
101 | if !params[:query_id].blank? |
|
126 | if !params[:query_id].blank? |
@@ -433,6 +433,25 class IssuesControllerTest < ActionController::TestCase | |||||
433 | assert lines.detect {|line| line.include?('"MySQL, Oracle"')} |
|
433 | assert lines.detect {|line| line.include?('"MySQL, Oracle"')} | |
434 | end |
|
434 | end | |
435 |
|
435 | |||
|
436 | def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator | |||
|
437 | field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float') | |||
|
438 | issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'}) | |||
|
439 | ||||
|
440 | with_settings :default_language => 'fr' do | |||
|
441 | get :index, :format => 'csv', :columns => 'all' | |||
|
442 | assert_response :success | |||
|
443 | issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s} | |||
|
444 | assert_include '185,60', issue_line | |||
|
445 | end | |||
|
446 | ||||
|
447 | with_settings :default_language => 'en' do | |||
|
448 | get :index, :format => 'csv', :columns => 'all' | |||
|
449 | assert_response :success | |||
|
450 | issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s} | |||
|
451 | assert_include '185.60', issue_line | |||
|
452 | end | |||
|
453 | end | |||
|
454 | ||||
436 | def test_index_csv_big_5 |
|
455 | def test_index_csv_big_5 | |
437 | with_settings :default_language => "zh-TW" do |
|
456 | with_settings :default_language => "zh-TW" do | |
438 | str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88" |
|
457 | str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88" | |
@@ -453,8 +472,8 class IssuesControllerTest < ActionController::TestCase | |||||
453 | if str_utf8.respond_to?(:force_encoding) |
|
472 | if str_utf8.respond_to?(:force_encoding) | |
454 | s1.force_encoding('Big5') |
|
473 | s1.force_encoding('Big5') | |
455 | end |
|
474 | end | |
456 |
assert lines[0] |
|
475 | assert_include s1, lines[0] | |
457 | assert lines[1].include?(str_big5) |
|
476 | assert_include str_big5, lines[1] | |
458 | end |
|
477 | end | |
459 | end |
|
478 | end | |
460 |
|
479 |
General Comments 0
You need to be logged in to leave comments.
Login now