From faa3d984ab0a44da354b901f4962d3441b800f99 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Lang <jp_lang@yahoo.fr>
Date: Sun, 24 Jun 2007 16:07:06 +0000
Subject: [PATCH] Added time report. Report can be generated by
 member/activity/tracker/version and year/month/week for the selected period.

git-svn-id: http://redmine.rubyforge.org/svn/trunk@572 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
 app/controllers/timelog_controller.rb      | 95 +++++++++++++++++++++-
 app/helpers/timelog_helper.rb              | 28 +++++++
 app/models/time_entry.rb                   | 17 ++++
 app/views/reports/issue_report.rhtml       | 12 +--
 app/views/timelog/_report_criteria.rhtml   | 17 ++++
 app/views/timelog/report.rhtml             | 52 ++++++++++++
 lang/bg.yml                                |  7 +-
 lang/de.yml                                |  7 +-
 lang/en.yml                                |  7 +-
 lang/es.yml                                |  7 +-
 lang/fr.yml                                |  7 +-
 lang/it.yml                                |  7 +-
 lang/ja.yml                                |  7 +-
 lang/nl.yml                                |  7 +-
 lang/pt-br.yml                             |  7 +-
 lang/pt.yml                                |  7 +-
 lang/sv.yml                                |  7 +-
 lang/zh.yml                                |  7 +-
 test/fixtures/time_entries.yml             | 43 ++++++++++
 test/functional/timelog_controller_test.rb | 52 ++++++++++++
 20 files changed, 382 insertions(+), 18 deletions(-)
 create mode 100644 app/views/timelog/_report_criteria.rhtml
 create mode 100644 app/views/timelog/report.rhtml
 create mode 100644 test/fixtures/time_entries.yml
 create mode 100644 test/functional/timelog_controller_test.rb

diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb
index da323fbf1..bed6b1c07 100644
--- a/app/controllers/timelog_controller.rb
+++ b/app/controllers/timelog_controller.rb
@@ -1,13 +1,106 @@
+# redMine - project management software
+# Copyright (C) 2006-2007  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 class TimelogController < ApplicationController
   layout 'base'
   
   before_filter :find_project
   before_filter :authorize, :only => :edit
-  before_filter :check_project_privacy, :only => :details
+  before_filter :check_project_privacy, :except => :edit
 
   helper :sort
   include SortHelper
   
+  def report
+    @available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
+                                          :values => @project.versions,
+                                          :label => :label_version},
+                             'category' => {:sql => "#{Issue.table_name}.category_id",
+                                            :values => @project.issue_categories,
+                                            :label => :field_category},
+                             'member' => {:sql => "#{TimeEntry.table_name}.user_id",
+                                         :values => @project.users,
+                                         :label => :label_member},
+                             'tracker' => {:sql => "#{Issue.table_name}.tracker_id",
+                                          :values => Tracker.find(:all),
+                                          :label => :label_tracker},
+                             'activity' => {:sql => "#{TimeEntry.table_name}.activity_id",
+                                           :values => Enumeration::get_values('ACTI'),
+                                           :label => :label_activity}
+                           }
+    
+    @criterias = params[:criterias] || []
+    @criterias = @criterias.select{|criteria| @available_criterias.has_key? criteria}
+    @criterias.uniq!
+    
+    @columns = (params[:period] && %w(year month week).include?(params[:period])) ? params[:period] : 'month'
+    
+    if params[:date_from]
+      begin; @date_from = params[:date_from].to_date; rescue; end
+    end
+    if params[:date_to]
+      begin; @date_to = params[:date_to].to_date; rescue; end
+    end
+    @date_from ||= Date.civil(Date.today.year, 1, 1)
+    @date_to ||= Date.civil(Date.today.year, Date.today.month+1, 1) - 1
+    
+    unless @criterias.empty?
+      sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
+      sql_group_by = @criterias.collect{|criteria| @available_criterias[criteria][:sql]}.join(', ')
+      
+      sql = "SELECT #{sql_select}, tyear, tmonth, tweek, SUM(hours) AS hours"
+      sql << " FROM #{TimeEntry.table_name} LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
+      sql << " WHERE spent_on BETWEEN '%s' AND '%s'" % [ActiveRecord::Base.connection.quoted_date(@date_from.to_time), ActiveRecord::Base.connection.quoted_date(@date_to.to_time)]
+      sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek"
+      
+      @hours = ActiveRecord::Base.connection.select_all(sql)
+      
+      @hours.each do |row|
+        case @columns
+        when 'year'
+          row['year'] = row['tyear']
+        when 'month'
+          row['month'] = "#{row['tyear']}-#{row['tmonth']}"
+        when 'week'
+          row['week'] = "#{row['tyear']}-#{row['tweek']}"
+        end
+      end
+    end
+       
+    @periods = []
+    date_from = @date_from
+    # 100 columns max
+    while date_from < @date_to && @periods.length < 100
+      case @columns
+      when 'year'
+        @periods << "#{date_from.year}"
+        date_from = date_from >> 12
+      when 'month'
+        @periods << "#{date_from.year}-#{date_from.month}"
+        date_from = date_from >> 1
+      when 'week'
+        @periods << "#{date_from.year}-#{date_from.cweek}"
+        date_from = date_from + 7
+      end
+    end
+    
+    render :layout => false if request.xhr?
+  end
+  
   def details
     sort_init 'spent_on', 'desc'
     sort_update
diff --git a/app/helpers/timelog_helper.rb b/app/helpers/timelog_helper.rb
index 9054ccd18..22e4eba0b 100644
--- a/app/helpers/timelog_helper.rb
+++ b/app/helpers/timelog_helper.rb
@@ -1,2 +1,30 @@
+# redMine - project management software
+# Copyright (C) 2006  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 module TimelogHelper
+  def select_hours(data, criteria, value)
+    data.select {|row| row[criteria] == value.to_s}
+  end
+  
+  def sum_hours(data)
+    sum = 0
+    data.each do |row|
+      sum += row['hours'].to_f
+    end
+    sum
+  end
 end
diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb
index c37f5dc86..905857073 100644
--- a/app/models/time_entry.rb
+++ b/app/models/time_entry.rb
@@ -1,3 +1,20 @@
+# redMine - project management software
+# Copyright (C) 2006-2007  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 class TimeEntry < ActiveRecord::Base
   # could have used polymorphic association
   # project association here allows easy loading of time entries at project level with one database trip
diff --git a/app/views/reports/issue_report.rhtml b/app/views/reports/issue_report.rhtml
index 3af936a5f..bf40e79ae 100644
--- a/app/views/reports/issue_report.rhtml
+++ b/app/views/reports/issue_report.rhtml
@@ -1,11 +1,13 @@
-<h2><%=l(:label_report_plural)%></h2>
-
 <% if @total_hours %>
-<h3 class="textright"><%= l(:label_spent_time) %>:
-<%= link_to(lwr(:label_f_hour, @total_hours), {:controller => 'timelog', :action => 'details', :project_id => @project}, :class => 'icon icon-time') %>
-</h3>
+<div style="float:right;text-align:right;">
+<strong><%= l(:label_spent_time) %></strong>: <span class="icon icon-time"><%= lwr(:label_f_hour, @total_hours) %></span><br />
+<%= link_to(l(:label_details), {:controller => 'timelog', :action => 'details', :project_id => @project}) %> |
+<%= link_to(l(:label_report), {:controller => 'timelog', :action => 'report', :project_id => @project}) %>
+</div>
 <% end %>
 
+<h2><%=l(:label_report_plural)%></h2>
+
 <div class="splitcontentleft">
 <h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('zoom_in.png'), :detail => 'tracker' %></h3>
 <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %>
diff --git a/app/views/timelog/_report_criteria.rhtml b/app/views/timelog/_report_criteria.rhtml
new file mode 100644
index 000000000..e4f5fa39a
--- /dev/null
+++ b/app/views/timelog/_report_criteria.rhtml
@@ -0,0 +1,17 @@
+<% @available_criterias[criterias[level]][:values].each do |value| %>
+<tr class="<%= cycle('odd', 'even') if criterias.length < level + 2 %>">
+<%= '<td></td>' * level %>
+<td><%= value.name %></td>
+<%= '<td></td>' * (criterias.length - level - 1) %>
+<% hours_for_value = select_hours(hours, criterias[level], value.id) %>
+  <% @periods.each do |period| %>
+    <% sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s)) %>
+    <td align="center"><%= sum > 0 ? sum : "-" %></td>
+  <% end %>
+</tr>
+<% if criterias.length > level+1 %>
+  <%= render(:partial => 'report_criteria', :locals => {:criterias => criterias, :hours => hours_for_value, :level => (level + 1)}) %>
+<% end %>
+
+<% end %>
+<% reset_cycle %>
diff --git a/app/views/timelog/report.rhtml b/app/views/timelog/report.rhtml
new file mode 100644
index 000000000..4fabfe3dd
--- /dev/null
+++ b/app/views/timelog/report.rhtml
@@ -0,0 +1,52 @@
+<h2><%= l(:label_spent_time) %></h2>
+
+<% form_remote_tag(:url => {:project_id => @project}, :update => 'content') do %>
+  <% @criterias.each do |criteria| %>
+    <%= hidden_field_tag 'criterias[]', criteria %>
+  <% end %>
+  <p>
+  <%= l(:label_date_from) %>: <%= text_field_tag 'date_from', @date_from, :size => 10 %><%= calendar_for('date_from') %>
+  &nbsp;
+  <%= l(:label_date_to) %>: <%= text_field_tag 'date_to', @date_to, :size => 10 %><%= calendar_for('date_to') %>
+  &nbsp;
+  <%= l(:label_details) %>:
+  <%= select_tag 'period', options_for_select([[l(:label_year), 'year'],
+                                               [l(:label_month), 'month'],
+                                               [l(:label_week), 'week']], @columns) %>
+  &nbsp;
+  <%= submit_tag l(:button_apply) %>
+  <%= link_to_remote l(:button_clear), {:url => {:project_id => @project}, :update => 'content'}, :class => 'icon icon-reload' %>
+  </p>
+
+  <% if @criterias.length < 3 %>
+  <p><%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l(@available_criterias[k][:label]), k]}), :onchange => "this.form.onsubmit();") %></p>
+  <% end %>
+  
+<br />
+
+<% unless @criterias.empty? %>  
+<table class="list">
+<thead>
+<tr>
+<% @criterias.each do |criteria| %>
+  <th width="15%"><%= l(@available_criterias[criteria][:label]) %></th>
+<% end %>
+<% @periods.each do |period| %>
+  <th width="<%= ((100 - @criterias.length * 15 - 15 ) / @periods.length).to_i %>%"><%= period %></th>
+<% end %>
+</tr>
+</thead>
+
+<tbody>
+<%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
+</tbody>
+</table>
+<% end %>
+<% end %>
+
+<% content_for :header_tags do %>
+<%= javascript_include_tag 'calendar/calendar' %>
+<%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
+<%= javascript_include_tag 'calendar/calendar-setup' %>
+<%= stylesheet_link_tag 'calendar' %>
+<% end %>
diff --git a/lang/bg.yml b/lang/bg.yml
index a91059f79..3d632273e 100644
--- a/lang/bg.yml
+++ b/lang/bg.yml
@@ -286,7 +286,7 @@ label_none: никакви
 label_next: Следващ
 label_previous: Предишен
 label_used_by: Използва се от
-label_details: Детайли...
+label_details: Детайли
 label_add_note: Добавяне на бележка
 label_per_page: На страница
 label_calendar: Календар
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Вход
 button_submit: Изпращане
diff --git a/lang/de.yml b/lang/de.yml
index 973e4fd91..03e7002f6 100644
--- a/lang/de.yml
+++ b/lang/de.yml
@@ -286,7 +286,7 @@ label_none: kein
 label_next: Weiter
 label_previous: Zurück
 label_used_by: Benutzt von
-label_details: Details...
+label_details: Details
 label_add_note: Kommentar hinzufügen
 label_per_page: Pro Seite
 label_calendar: Kalender
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Einloggen
 button_submit: OK
diff --git a/lang/en.yml b/lang/en.yml
index 6c3c38f78..e24a2f53f 100644
--- a/lang/en.yml
+++ b/lang/en.yml
@@ -286,7 +286,7 @@ label_none: none
 label_next: Next
 label_previous: Previous
 label_used_by: Used by
-label_details: Details...
+label_details: Details
 label_add_note: Add a note
 label_per_page: Per page
 label_calendar: Calendar
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Login
 button_submit: Submit
diff --git a/lang/es.yml b/lang/es.yml
index 717c1bf6b..8c4a0ba90 100644
--- a/lang/es.yml
+++ b/lang/es.yml
@@ -286,7 +286,7 @@ label_none: ninguno
 label_next: Próximo
 label_previous: Precedente
 label_used_by: Utilizado por
-label_details: Detalles...
+label_details: Detalles
 label_add_note: Agregar una nota
 label_per_page: Por la página
 label_calendar: Calendario
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Conexión
 button_submit: Someter
diff --git a/lang/fr.yml b/lang/fr.yml
index bab251425..34449c2ce 100644
--- a/lang/fr.yml
+++ b/lang/fr.yml
@@ -286,7 +286,7 @@ label_none: aucun
 label_next: Suivant
 label_previous: Précédent
 label_used_by: Utilisé par
-label_details: Détails...
+label_details: Détails
 label_add_note: Ajouter une note
 label_per_page: Par page
 label_calendar: Calendrier
@@ -397,6 +397,11 @@ label_message_last: Dernier message
 label_message_new: Nouveau message
 label_reply_plural: Réponses
 label_send_information: Envoyer les informations à l'utilisateur
+label_year: Année
+label_month: Mois
+label_week: Semaine
+label_date_from: Du
+label_date_to: Au
 
 button_login: Connexion
 button_submit: Soumettre
diff --git a/lang/it.yml b/lang/it.yml
index 28d860af0..583c3b7c6 100644
--- a/lang/it.yml
+++ b/lang/it.yml
@@ -286,7 +286,7 @@ label_none: nessuno
 label_next: Successivo
 label_previous: Precedente
 label_used_by: Usato da
-label_details: Dettagli...
+label_details: Dettagli
 label_add_note: Aggiungi una nota
 label_per_page: Per pagina
 label_calendar: Calendario
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Login
 button_submit: Invia
diff --git a/lang/ja.yml b/lang/ja.yml
index 67f48d5ac..a7f4b54c3 100644
--- a/lang/ja.yml
+++ b/lang/ja.yml
@@ -287,7 +287,7 @@ label_none: なし
 label_next: 次
 label_previous: 前
 label_used_by: 使用中
-label_details: 詳細...
+label_details: 詳細
 label_add_note: 注記を追加
 label_per_page: ページ毎
 label_calendar: カレンダー
@@ -398,6 +398,11 @@ label_message_last: 最新のメッセージ
 label_message_new: 新しいメッセージ
 label_reply_plural: 返答
 label_send_information: アカウント情報をユーザに送信
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: ログイン
 button_submit: 変更
diff --git a/lang/nl.yml b/lang/nl.yml
index 1c115369d..34b6897ca 100644
--- a/lang/nl.yml
+++ b/lang/nl.yml
@@ -286,7 +286,7 @@ label_none: geen
 label_next: Volgende
 label_previous: Vorige
 label_used_by: Gebruikt door
-label_details: Details...
+label_details: Details
 label_add_note: Voeg een notitie toe
 label_per_page: Per pagina
 label_calendar: Kalender
@@ -397,6 +397,11 @@ label_message_last: Laatste bericht
 label_message_new: Nieuw bericht
 label_reply_plural: Antwoorden
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Inloggen
 button_submit: Toevoegen
diff --git a/lang/pt-br.yml b/lang/pt-br.yml
index 1090c6907..c37027883 100644
--- a/lang/pt-br.yml
+++ b/lang/pt-br.yml
@@ -286,7 +286,7 @@ label_none: nenhum
 label_next: Proximo
 label_previous: Anterior
 label_used_by: Usado por
-label_details: Detalhes...
+label_details: Detalhes
 label_add_note: Adicionar nota
 label_per_page: Por pagina
 label_calendar: Calendario
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Login
 button_submit: Enviar
diff --git a/lang/pt.yml b/lang/pt.yml
index b1c02bc95..09236a347 100644
--- a/lang/pt.yml
+++ b/lang/pt.yml
@@ -286,7 +286,7 @@ label_none: nenhum
 label_next: Próximo
 label_previous: Anterior
 label_used_by: Usado por
-label_details: Detalhes...
+label_details: Detalhes
 label_add_note: Adicionar nota
 label_per_page: Por página
 label_calendar: Calendário
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Login
 button_submit: Enviar
diff --git a/lang/sv.yml b/lang/sv.yml
index f781db9cc..f56ef2ef2 100644
--- a/lang/sv.yml
+++ b/lang/sv.yml
@@ -286,7 +286,7 @@ label_none: inga
 label_next: Nästa
 label_previous: Föregående
 label_used_by: Använd av
-label_details: Detaljer...
+label_details: Detaljer
 label_add_note: Lägg till anteckning
 label_per_page: Per sida
 label_calendar: Kalender
@@ -397,6 +397,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: Logga in
 button_submit: Skicka
diff --git a/lang/zh.yml b/lang/zh.yml
index e317afa20..850c9b56e 100644
--- a/lang/zh.yml
+++ b/lang/zh.yml
@@ -289,7 +289,7 @@ label_none: æ— 
 label_next: 下一个
 label_previous: 上一个
 label_used_by: 使用中
-label_details: 详情...
+label_details: 详情
 label_add_note: 添加说明
 label_per_page: 每面
 label_calendar: 日历
@@ -399,6 +399,11 @@ label_message_last: Last message
 label_message_new: New message
 label_reply_plural: Replies
 label_send_information: Send account information to the user
+label_year: Year
+label_month: Month
+label_week: Week
+label_date_from: From
+label_date_to: To
 
 button_login: 登录
 button_submit: 提交
diff --git a/test/fixtures/time_entries.yml b/test/fixtures/time_entries.yml
new file mode 100644
index 000000000..4e4ff6896
--- /dev/null
+++ b/test/fixtures/time_entries.yml
@@ -0,0 +1,43 @@
+--- 
+time_entries_001: 
+  created_on: 2007-03-23 12:54:18 +01:00
+  tweek: 12
+  tmonth: 3
+  project_id: 1
+  comments: My hours
+  updated_on: 2007-03-23 12:54:18 +01:00
+  activity_id: 8
+  spent_on: 2007-03-23
+  issue_id: 1
+  id: 1
+  hours: 4.25
+  user_id: 2
+  tyear: 2007
+time_entries_002: 
+  created_on: 2007-03-23 14:11:04 +01:00
+  tweek: 12
+  tmonth: 3
+  project_id: 1
+  comments: ""
+  updated_on: 2007-03-23 14:11:04 +01:00
+  activity_id: 8
+  spent_on: 2007-03-23
+  issue_id: 1
+  id: 2
+  hours: 150.0
+  user_id: 1
+  tyear: 2007
+time_entries_003: 
+  created_on: 2007-04-21 12:20:48 +02:00
+  tweek: 16
+  tmonth: 4
+  project_id: 1
+  comments: ""
+  updated_on: 2007-04-21 12:20:48 +02:00
+  activity_id: 8
+  spent_on: 2007-04-21
+  issue_id: 2
+  id: 3
+  hours: 1.0
+  user_id: 1
+  tyear: 2007
diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb
new file mode 100644
index 000000000..62f1a2e7f
--- /dev/null
+++ b/test/functional/timelog_controller_test.rb
@@ -0,0 +1,52 @@
+# redMine - project management software
+# Copyright (C) 2006-2007  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+require File.dirname(__FILE__) + '/../test_helper'
+require 'timelog_controller'
+
+# Re-raise errors caught by the controller.
+class TimelogController; def rescue_action(e) raise e end; end
+
+class TimelogControllerTest < Test::Unit::TestCase
+  fixtures :time_entries, :issues
+
+  def setup
+    @controller = TimelogController.new
+    @request    = ActionController::TestRequest.new
+    @response   = ActionController::TestResponse.new
+  end
+
+  def test_report_no_criteria
+    get :report, :project_id => 1
+    assert_response :success
+    assert_template 'report'
+  end
+  
+  def test_report_one_criteria
+    get :report, :project_id => 1, :period => "month", :date_from => "2007-01-01", :date_to => "2007-12-31", :criterias => ["member"]
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:hours)
+  end
+  
+  def test_report_two_criterias
+    get :report, :project_id => 1, :period => "week", :date_from => "2007-01-01", :date_to => "2007-12-31", :criterias => ["member", "activity"]
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:hours)
+  end
+end
-- 
GitLab