Index: config/settings.yml =================================================================== --- config/settings.yml (revision 12132) +++ config/settings.yml (working copy) @@ -230,3 +230,6 @@ default: - '6' - '7' +standard_man_hours_a_day: + format: int + default: 8 \ No newline at end of file Index: config/locales/en.yml =================================================================== --- config/locales/en.yml (revision 12132) +++ config/locales/en.yml (working copy) @@ -1092,3 +1092,5 @@ description_date_from: Enter start date description_date_to: Enter end date text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.
Once saved, the identifier cannot be changed.' + setting_standard_man_hours_a_day: Standard man hours a day + utilization: Utilization \ No newline at end of file Index: app/helpers/timelog_helper.rb =================================================================== --- app/helpers/timelog_helper.rb (revision 12132) +++ app/helpers/timelog_helper.rb (working copy) @@ -101,6 +101,29 @@ end end + def calculate_availability(columns, hours, period) + hours = hours.to_f + std_hours = Setting.standard_man_hours_a_day.to_i + business_days = case columns + when "week" + 5 + when "month" + period = period.split('-') + year, month = period[0].to_i, period[1].to_i + start_date = Date.new(year, month) + TimeEntry.business_days_between start_date, start_date.end_of_month + when "day" + 1 + when "year" + year = period.to_i + start_date = Date.new(year) + TimeEntry.business_days_between start_date, start_date.end_of_year + end + availability = hours/(std_hours * business_days) + "%.1f" % (availability * 100) + end + + def report_to_csv(report) decimal_separator = l(:general_csv_decimal_separator) export = FCSV.generate(:col_sep => l(:general_csv_separator)) do |csv| Index: app/models/time_entry.rb =================================================================== --- app/models/time_entry.rb (revision 12132) +++ app/models/time_entry.rb (working copy) @@ -116,4 +116,15 @@ def editable_by?(usr) (usr == user && usr.allowed_to?(:edit_own_time_entries, project)) || usr.allowed_to?(:edit_time_entries, project) end + + def self.business_days_between(date1, date2) + business_days = 0 + date = date2 + while date >= date1 + business_days += 1 unless date.saturday? or date.sunday? + date = date - 1 + end + business_days + end + end Index: app/controllers/timelog_controller.rb =================================================================== --- app/controllers/timelog_controller.rb (revision 12132) +++ app/controllers/timelog_controller.rb (working copy) @@ -82,6 +82,8 @@ @report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope) + @show_utilization = (params[:criteria].present? and params[:criteria].include? "utilization") + respond_to do |format| format.html { render :layout => !request.xhr? } format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') } Index: app/views/timelog/report.html.erb =================================================================== --- app/views/timelog/report.html.erb (revision 12132) +++ app/views/timelog/report.html.erb (working copy) @@ -12,6 +12,8 @@ <% @report.criteria.each do |criterion| %> <%= hidden_field_tag 'criteria[]', criterion, :id => nil %> <% end %> + <%= (hidden_field_tag 'criteria[]', "utilization", :id => nil) if @show_utilization %> + <%= render :partial => 'timelog/date_range' %>

: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'], @@ -19,8 +21,9 @@ [l(:label_week), 'week'], [l(:label_day_plural).titleize, 'day']], @report.columns), :onchange => "this.form.submit();" %> - - : <%= select_tag('criteria[]', options_for_select([[]] + (@report.available_criteria.keys - @report.criteria).collect{|k| [l_or_humanize(@report.available_criteria[k][:label]), k]}), + <% select_opts = [[]] + (@report.available_criteria.keys - @report.criteria).collect{|k| [l_or_humanize(@report.available_criteria[k][:label]), k]} %> + <% select_opts = select_opts + [[l(:utilization), "utilization"]] if (@report.criteria.count > 0 and !@show_utilization) %> + : <%= select_tag('criteria[]', options_for_select(select_opts), :onchange => "this.form.submit();", :style => 'width: 200px', :id => nil, @@ -56,7 +59,12 @@ <% total = 0 -%> <% @report.periods.each do |period| -%> <% sum = sum_hours(select_hours(@report.hours, @report.columns, period.to_s)); total += sum -%> - <%= html_hours("%.2f" % sum) if sum > 0 %> + <%= html_hours("%.2f" % sum) if sum > 0 %> + <% if @show_utilization and sum > 0 %> +
+ (<%= calculate_availability(@report.columns, "%.2f" % sum, period.to_s) %>%) + <% end %> + <% end -%> <%= html_hours("%.2f" % total) if total > 0 %> Index: app/views/timelog/_report_criteria.html.erb =================================================================== --- app/views/timelog/_report_criteria.html.erb (revision 12132) +++ app/views/timelog/_report_criteria.html.erb (working copy) @@ -8,7 +8,12 @@ <% total = 0 -%> <% @report.periods.each do |period| -%> <% sum = sum_hours(select_hours(hours_for_value, @report.columns, period.to_s)); total += sum -%> - <%= html_hours("%.2f" % sum) if sum > 0 %> + <%= html_hours("%.2f" % sum) if sum > 0; %> + <% if @show_utilization and sum > 0 %> +
+ (<%= calculate_availability(@report.columns, "%.2f" % sum, period.to_s) %>%) + <% end %> + <% end -%> <%= html_hours("%.2f" % total) if total > 0 %> Index: app/views/settings/_general.html.erb =================================================================== --- app/views/settings/_general.html.erb (revision 12132) +++ app/views/settings/_general.html.erb (working copy) @@ -33,6 +33,8 @@

<%= setting_text_field :repositories_encodings, :size => 60 %> <%= l(:text_comma_separated) %>

+ +

<%= setting_text_field :standard_man_hours_a_day, :size => 6 %>

<%= call_hook(:view_settings_general_form) %>