annotate app/helpers/timelog_helper.rb @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 513646585e45
children cbb26bc654de
rev   line source
Chris@0 1 # redMine - project management software
Chris@0 2 # Copyright (C) 2006 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 module TimelogHelper
Chris@0 19 include ApplicationHelper
Chris@0 20
Chris@0 21 def render_timelog_breadcrumb
Chris@0 22 links = []
Chris@0 23 links << link_to(l(:label_project_all), {:project_id => nil, :issue_id => nil})
Chris@0 24 links << link_to(h(@project), {:project_id => @project, :issue_id => nil}) if @project
Chris@0 25 if @issue
Chris@0 26 if @issue.visible?
Chris@0 27 links << link_to_issue(@issue, :subject => false)
Chris@0 28 else
Chris@0 29 links << "##{@issue.id}"
Chris@0 30 end
Chris@0 31 end
Chris@0 32 breadcrumb links
Chris@0 33 end
Chris@0 34
Chris@0 35 # Returns a collection of activities for a select field. time_entry
Chris@0 36 # is optional and will be used to check if the selected TimeEntryActivity
Chris@0 37 # is active.
Chris@0 38 def activity_collection_for_select_options(time_entry=nil, project=nil)
Chris@0 39 project ||= @project
Chris@0 40 if project.nil?
Chris@0 41 activities = TimeEntryActivity.shared.active
Chris@0 42 else
Chris@0 43 activities = project.activities
Chris@0 44 end
Chris@0 45
Chris@0 46 collection = []
Chris@0 47 if time_entry && time_entry.activity && !time_entry.activity.active?
Chris@0 48 collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ]
Chris@0 49 else
Chris@0 50 collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
Chris@0 51 end
Chris@0 52 activities.each { |a| collection << [a.name, a.id] }
Chris@0 53 collection
Chris@0 54 end
Chris@0 55
Chris@0 56 def select_hours(data, criteria, value)
Chris@0 57 if value.to_s.empty?
Chris@0 58 data.select {|row| row[criteria].blank? }
Chris@0 59 else
Chris@0 60 data.select {|row| row[criteria].to_s == value.to_s}
Chris@0 61 end
Chris@0 62 end
Chris@0 63
Chris@0 64 def sum_hours(data)
Chris@0 65 sum = 0
Chris@0 66 data.each do |row|
Chris@0 67 sum += row['hours'].to_f
Chris@0 68 end
Chris@0 69 sum
Chris@0 70 end
Chris@0 71
Chris@0 72 def options_for_period_select(value)
Chris@0 73 options_for_select([[l(:label_all_time), 'all'],
Chris@0 74 [l(:label_today), 'today'],
Chris@0 75 [l(:label_yesterday), 'yesterday'],
Chris@0 76 [l(:label_this_week), 'current_week'],
Chris@0 77 [l(:label_last_week), 'last_week'],
Chris@0 78 [l(:label_last_n_days, 7), '7_days'],
Chris@0 79 [l(:label_this_month), 'current_month'],
Chris@0 80 [l(:label_last_month), 'last_month'],
Chris@0 81 [l(:label_last_n_days, 30), '30_days'],
Chris@0 82 [l(:label_this_year), 'current_year']],
Chris@0 83 value)
Chris@0 84 end
Chris@0 85
Chris@0 86 def entries_to_csv(entries)
Chris@0 87 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
Chris@0 88 decimal_separator = l(:general_csv_decimal_separator)
Chris@0 89 custom_fields = TimeEntryCustomField.find(:all)
Chris@0 90 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
Chris@0 91 # csv header fields
Chris@0 92 headers = [l(:field_spent_on),
Chris@0 93 l(:field_user),
Chris@0 94 l(:field_activity),
Chris@0 95 l(:field_project),
Chris@0 96 l(:field_issue),
Chris@0 97 l(:field_tracker),
Chris@0 98 l(:field_subject),
Chris@0 99 l(:field_hours),
Chris@0 100 l(:field_comments)
Chris@0 101 ]
Chris@0 102 # Export custom fields
Chris@0 103 headers += custom_fields.collect(&:name)
Chris@0 104
Chris@0 105 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
Chris@0 106 # csv lines
Chris@0 107 entries.each do |entry|
Chris@0 108 fields = [format_date(entry.spent_on),
Chris@0 109 entry.user,
Chris@0 110 entry.activity,
Chris@0 111 entry.project,
Chris@0 112 (entry.issue ? entry.issue.id : nil),
Chris@0 113 (entry.issue ? entry.issue.tracker : nil),
Chris@0 114 (entry.issue ? entry.issue.subject : nil),
Chris@0 115 entry.hours.to_s.gsub('.', decimal_separator),
Chris@0 116 entry.comments
Chris@0 117 ]
Chris@0 118 fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) }
Chris@0 119
Chris@0 120 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
Chris@0 121 end
Chris@0 122 end
Chris@0 123 export
Chris@0 124 end
Chris@0 125
Chris@0 126 def format_criteria_value(criteria, value)
Chris@0 127 if value.blank?
Chris@0 128 l(:label_none)
Chris@0 129 elsif k = @available_criterias[criteria][:klass]
Chris@0 130 obj = k.find_by_id(value.to_i)
Chris@0 131 if obj.is_a?(Issue)
Chris@0 132 obj.visible? ? "#{obj.tracker} ##{obj.id}: #{obj.subject}" : "##{obj.id}"
Chris@0 133 else
Chris@0 134 obj
Chris@0 135 end
Chris@0 136 else
Chris@0 137 format_value(value, @available_criterias[criteria][:format])
Chris@0 138 end
Chris@0 139 end
Chris@0 140
Chris@0 141 def report_to_csv(criterias, periods, hours)
Chris@0 142 export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv|
Chris@0 143 # Column headers
Chris@0 144 headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
Chris@0 145 headers += periods
Chris@0 146 headers << l(:label_total)
Chris@0 147 csv << headers.collect {|c| to_utf8(c) }
Chris@0 148 # Content
Chris@0 149 report_criteria_to_csv(csv, criterias, periods, hours)
Chris@0 150 # Total row
Chris@0 151 row = [ l(:label_total) ] + [''] * (criterias.size - 1)
Chris@0 152 total = 0
Chris@0 153 periods.each do |period|
Chris@0 154 sum = sum_hours(select_hours(hours, @columns, period.to_s))
Chris@0 155 total += sum
Chris@0 156 row << (sum > 0 ? "%.2f" % sum : '')
Chris@0 157 end
Chris@0 158 row << "%.2f" %total
Chris@0 159 csv << row
Chris@0 160 end
Chris@0 161 export
Chris@0 162 end
Chris@0 163
Chris@0 164 def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
Chris@0 165 hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value|
Chris@0 166 hours_for_value = select_hours(hours, criterias[level], value)
Chris@0 167 next if hours_for_value.empty?
Chris@0 168 row = [''] * level
Chris@0 169 row << to_utf8(format_criteria_value(criterias[level], value))
Chris@0 170 row += [''] * (criterias.length - level - 1)
Chris@0 171 total = 0
Chris@0 172 periods.each do |period|
Chris@0 173 sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
Chris@0 174 total += sum
Chris@0 175 row << (sum > 0 ? "%.2f" % sum : '')
Chris@0 176 end
Chris@0 177 row << "%.2f" %total
Chris@0 178 csv << row
Chris@0 179
Chris@0 180 if criterias.length > level + 1
Chris@0 181 report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
Chris@0 182 end
Chris@0 183 end
Chris@0 184 end
Chris@0 185
Chris@0 186 def to_utf8(s)
Chris@0 187 @ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8')
Chris@0 188 begin; @ic.iconv(s.to_s); rescue; s.to_s; end
Chris@0 189 end
Chris@0 190 end