##// END OF EJS Templates
CSV export added to timelog report (#1009)....
Jean-Philippe Lang -
r1323:5d3454853956
parent child
Show More
@@ -112,7 +112,10 class TimelogController < ApplicationController
112 end
112 end
113 end
113 end
114
114
115 render :layout => false if request.xhr?
115 respond_to do |format|
116 format.html { render :layout => !request.xhr? }
117 format.csv { send_data(report_to_csv(@criterias, @periods, @hours).read, :type => 'text/csv; header=present', :filename => 'timelog.csv') }
118 end
116 end
119 end
117
120
118 def details
121 def details
@@ -76,4 +76,56 module TimelogHelper
76 export.rewind
76 export.rewind
77 export
77 export
78 end
78 end
79
80 def report_to_csv(criterias, periods, hours)
81 export = StringIO.new
82 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
83 # Column headers
84 headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
85 headers += periods
86 headers << l(:label_total)
87 csv << headers.collect {|c| to_utf8(c) }
88 # Content
89 report_criteria_to_csv(csv, criterias, periods, hours)
90 # Total row
91 row = [ l(:label_total) ] + [''] * (criterias.size - 1)
92 total = 0
93 periods.each do |period|
94 sum = sum_hours(select_hours(hours, @columns, period.to_s))
95 total += sum
96 row << (sum > 0 ? "%.2f" % sum : '')
97 end
98 row << "%.2f" %total
99 csv << row
100 end
101 export.rewind
102 export
103 end
104
105 def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
106 hours.collect {|h| h[criterias[level]]}.uniq.each do |value|
107 hours_for_value = select_hours(hours, criterias[level], value)
108 next if hours_for_value.empty?
109 row = [''] * level
110 row << to_utf8(value.nil? ? l(:label_none) : @available_criterias[criterias[level]][:klass].find_by_id(value))
111 row += [''] * (criterias.length - level - 1)
112 total = 0
113 periods.each do |period|
114 sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
115 total += sum
116 row << (sum > 0 ? "%.2f" % sum : '')
117 end
118 row << "%.2f" %total
119 csv << row
120
121 if criterias.length > level + 1
122 report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
123 end
124 end
125 end
126
127 def to_utf8(s)
128 @ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8')
129 begin; @ic.iconv(s.to_s); rescue; s.to_s; end
130 end
79 end
131 end
@@ -60,6 +60,11
60 </tr>
60 </tr>
61 </tbody>
61 </tbody>
62 </table>
62 </table>
63
64 <p class="other-formats">
65 <%= l(:label_export_to) %>
66 <span><%= link_to 'CSV', params.merge({:format => 'csv'}), :class => 'csv' %></span>
67 </p>
63 <% end %>
68 <% end %>
64 <% end %>
69 <% end %>
65
70
@@ -118,7 +118,18 class TimelogControllerTest < Test::Unit::TestCase
118 assert_template 'report'
118 assert_template 'report'
119 assert_not_nil assigns(:total_hours)
119 assert_not_nil assigns(:total_hours)
120 assert_equal "0.00", "%.2f" % assigns(:total_hours)
120 assert_equal "0.00", "%.2f" % assigns(:total_hours)
121 end
121 end
122
123 def test_report_csv_export
124 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
125 assert_response :success
126 assert_equal 'text/csv', @response.content_type
127 lines = @response.body.chomp.split("\n")
128 # Headers
129 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
130 # Total row
131 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
132 end
122
133
123 def test_details_at_project_level
134 def test_details_at_project_level
124 get :details, :project_id => 1
135 get :details, :project_id => 1
General Comments 0
You need to be logged in to leave comments. Login now