Index: test/functional/timelog_controller_test.rb
===================================================================
--- test/functional/timelog_controller_test.rb	(revision 3764)
+++ test/functional/timelog_controller_test.rb	(working copy)
@@ -173,6 +173,26 @@
     assert_equal "8.65", "%.2f" % assigns(:total_hours)
   end
   
+  def test_report_one_criteria_year_spanning_week
+    get :report, :project_id => 1, :columns => 'week', :from => "2009-12-01", :to => "2010-01-31", :criterias => ['project']
+
+    assert_response :success
+    assert_template 'report'
+    assert_not_nil assigns(:total_hours)
+    assert_equal "3.00", "%.2f" % assigns(:total_hours)
+    
+    # one entry for 2009-12 and one for 2010-01
+    assert_not_nil assigns(:hours)
+    assert_equal 2, assigns(:hours).count
+    
+    assigns(:hours).each do |week|
+      assert_equal "2009-53", week["week"]
+    end
+    hours = assigns(:hours).sum{|week| week["hours"].to_f}
+    assert_equal "3.00", "%.2f" % hours
+  end
+  
+  
   def test_report_two_criterias
     get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
     assert_response :success
Index: test/fixtures/time_entries.yml
===================================================================
--- test/fixtures/time_entries.yml	(revision 3764)
+++ test/fixtures/time_entries.yml	(working copy)
@@ -13,6 +13,7 @@
   hours: 4.25
   user_id: 2
   tyear: 2007
+  twyear: 2007
 time_entries_002: 
   created_on: 2007-03-23 14:11:04 +01:00
   tweek: 11
@@ -27,6 +28,7 @@
   hours: 150.0
   user_id: 1
   tyear: 2007
+  twyear: 2007
 time_entries_003: 
   created_on: 2007-04-21 12:20:48 +02:00
   tweek: 16
@@ -41,6 +43,7 @@
   hours: 1.0
   user_id: 1
   tyear: 2007
+  twyear: 2007
 time_entries_004: 
   created_on: 2007-04-22 12:20:48 +02:00
   tweek: 16
@@ -55,4 +58,34 @@
   hours: 7.65
   user_id: 1
   tyear: 2007
-  
+  twyear: 2007
+time_entries_005: 
+  created_on: 2010-04-22 12:20:48 +02:00
+  tweek: 53
+  tmonth: 12
+  project_id: 5
+  comments: "old year, old week"
+  updated_on: 2010-04-22 12:20:48 +02:00
+  activity_id: 11
+  spent_on: 2009-12-31
+  issue_id: 
+  id: 5
+  hours: 1
+  user_id: 1
+  tyear: 2009
+  twyear: 2009
+time_entries_006: 
+  created_on: 2010-04-22 12:20:48 +02:00
+  tweek: 53
+  tmonth: 1
+  project_id: 5
+  comments: "new year, old week"
+  updated_on: 2007-04-22 12:20:48 +02:00
+  activity_id: 11
+  spent_on: 2010-01-01
+  issue_id:
+  id: 6
+  hours: 2
+  user_id: 1
+  tyear: 2010
+  twyear: 2009
Index: app/models/time_entry.rb
===================================================================
--- app/models/time_entry.rb	(revision 3764)
+++ app/models/time_entry.rb	(working copy)
@@ -23,7 +23,7 @@
   belongs_to :user
   belongs_to :activity, :class_name => 'TimeEntryActivity', :foreign_key => 'activity_id'
   
-  attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek
+  attr_protected :project_id, :user_id, :tyear, :tmonth, :tweek, :twyear
 
   acts_as_customizable
   acts_as_event :title => Proc.new {|o| "#{l_hours(o.hours)} (#{(o.issue || o.project).event_title})"},
@@ -62,13 +62,14 @@
     write_attribute :hours, (h.is_a?(String) ? (h.to_hours || h) : h)
   end
   
-  # tyear, tmonth, tweek assigned where setting spent_on attributes
+  # tyear, tmonth, tweek, twyear assigned where setting spent_on attributes
   # these attributes make time aggregations easier
   def spent_on=(date)
     super
     self.tyear = spent_on ? spent_on.year : nil
     self.tmonth = spent_on ? spent_on.month : nil
     self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
+    self.twyear = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cwyear : nil
   end
   
   # Returns true if the time entry can be edited by usr, otherwise false
Index: app/controllers/timelog_controller.rb
===================================================================
--- app/controllers/timelog_controller.rb	(revision 3764)
+++ app/controllers/timelog_controller.rb	(working copy)
@@ -81,6 +81,7 @@
     @criterias = @criterias[0,3]
     
     @columns = (params[:columns] && %w(year month week day).include?(params[:columns])) ? params[:columns] : 'month'
+    year_column = (@columns == 'week' ? 'twyear' : 'tyear')
     
     retrieve_date_range
     
@@ -97,14 +98,14 @@
         sql_condition = "#{Issue.table_name}.root_id = #{@issue.root_id} AND #{Issue.table_name}.lft >= #{@issue.lft} AND #{Issue.table_name}.rgt <= #{@issue.rgt}"
       end
 
-      sql = "SELECT #{sql_select}, tyear, tmonth, tweek, spent_on, SUM(hours) AS hours"
+      sql = "SELECT #{sql_select}, #{year_column}, tmonth, tweek, spent_on, SUM(hours) AS hours"
       sql << " FROM #{TimeEntry.table_name}"
       sql << " LEFT JOIN #{Issue.table_name} ON #{TimeEntry.table_name}.issue_id = #{Issue.table_name}.id"
       sql << " LEFT JOIN #{Project.table_name} ON #{TimeEntry.table_name}.project_id = #{Project.table_name}.id"
       sql << " WHERE"
       sql << " (%s) AND" % sql_condition
       sql << " (spent_on BETWEEN '%s' AND '%s')" % [ActiveRecord::Base.connection.quoted_date(@from), ActiveRecord::Base.connection.quoted_date(@to)]
-      sql << " GROUP BY #{sql_group_by}, tyear, tmonth, tweek, spent_on"
+      sql << " GROUP BY #{sql_group_by}, #{year_column}, tmonth, tweek, spent_on"
       
       @hours = ActiveRecord::Base.connection.select_all(sql)
       
@@ -115,7 +116,7 @@
         when 'month'
           row['month'] = "#{row['tyear']}-#{row['tmonth']}"
         when 'week'
-          row['week'] = "#{row['tyear']}-#{row['tweek']}"
+          row['week'] = "#{row['twyear']}-#{row['tweek']}"
         when 'day'
           row['day'] = "#{row['spent_on']}"
         end
@@ -136,7 +137,7 @@
           @periods << "#{date_from.year}-#{date_from.month}"
           date_from = (date_from + 1.month).at_beginning_of_month
         when 'week'
-          @periods << "#{date_from.year}-#{date_from.to_date.cweek}"
+          @periods << "#{date_from.to_date.cwyear}-#{date_from.to_date.cweek}"
           date_from = (date_from + 7.day).at_beginning_of_week
         when 'day'
           @periods << "#{date_from.to_date}"
Index: db/migrate/20100630181445_add_year_of_week_to_time_entries.rb
===================================================================
--- db/migrate/20100630181445_add_year_of_week_to_time_entries.rb	(revision 0)
+++ db/migrate/20100630181445_add_year_of_week_to_time_entries.rb	(revision 0)
@@ -0,0 +1,20 @@
+class AddYearOfWeekToTimeEntries < ActiveRecord::Migration
+  class TimeEntry < ActiveRecord::Base
+  end
+  
+  def self.up
+    add_column :time_entries, :twyear, :integer
+    
+    TimeEntry.all.each do |t|
+      t.update_attributes({
+        :twyear => Date.civil(t.spent_on.year, t.spent_on.month, t.spent_on.day).cwyear
+      })
+    end
+    
+    change_column :time_entries, :twyear, :integer, :null => false
+  end
+
+  def self.down
+    remove_column :time_entries, :twyear
+  end
+end
