backlog 0.10.3 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.10.4 2007-09-25
2
+
3
+ === Features
4
+
5
+ * Now you can move tasks in and out of supertasks.
6
+
7
+ === Fixes
8
+
9
+ * Changed name of released WAR file back to include the version number since RubyForge only allows unique file names.
10
+ * Fixed bug where the "show period" action would fail if you tried to display the period of an unplanned task.
11
+ * Fixed bugs in the calculation of weekly work sheet and time sheet.
12
+
1
13
  == 0.10.3 2007-09-24
2
14
 
3
15
  * Removed "Active Sprint" from Group edit view, when there is no active sprint.
data/Rakefile CHANGED
@@ -44,7 +44,7 @@ end
44
44
 
45
45
  task :release_war do
46
46
  Rake::Task['war:standalone:create'].invoke
47
- war_pkg_file = "pkg/backlog.war"
47
+ war_pkg_file = "pkg/backlog-#{APP::VERSION}.war"
48
48
  if File.exists? 'backlog.war'
49
49
  File.makedirs 'pkg'
50
50
  File.move 'backlog.war', war_pkg_file
@@ -22,6 +22,10 @@ class PeriodsController < ApplicationController
22
22
  end
23
23
  if @selected_task
24
24
  @period = @selected_task.period
25
+ if @period.nil?
26
+ redirect_to :controller => 'backlogs', :action => :show, :id => @selected_task.backlog.id
27
+ return
28
+ end
25
29
  elsif params[:id] && @period = Period.find_by_id(params[:id])
26
30
  elsif @period = Period.find(:first)
27
31
  else
@@ -29,7 +33,7 @@ class PeriodsController < ApplicationController
29
33
  return
30
34
  end
31
35
  if @selected_task.nil?
32
- @selected_task = Task.find(:first, :conditions => "position = 1 AND period_id = #{@period.id}")
36
+ @selected_task = @period.open_tasks.first
33
37
  end
34
38
  @tasks = @period.open_tasks
35
39
  @completed_tasks = @period.completed_tasks.reverse
@@ -103,7 +107,7 @@ class PeriodsController < ApplicationController
103
107
  @works = Work.find_by_sql("SELECT w.* FROM works w LEFT OUTER JOIN tasks t ON t.id = w.task_id WHERE t.period_id = #{@period.id} ORDER BY w.completed_at")
104
108
  render :template => '/works/list'
105
109
  end
106
-
110
+
107
111
  def make_link
108
112
  if params[:id].to_i > 0
109
113
  render :partial => 'link', :layout => false, :locals => {:period => Period.find(params[:id])}
@@ -24,7 +24,7 @@ class TasksController < ApplicationController
24
24
  detour_to :controller => 'periods', :action => :new, :group_id => params[:task][:period_id][1..-1].to_i
25
25
  return
26
26
  end
27
-
27
+
28
28
  file = params[:task].delete(:file)
29
29
 
30
30
  @task = Task.new(params[:task])
@@ -84,7 +84,7 @@ class TasksController < ApplicationController
84
84
  end
85
85
  end
86
86
  end
87
-
87
+
88
88
  file = params[:task].delete(:file)
89
89
 
90
90
  if params[:task] && @task.update_attributes(params[:task])
@@ -156,14 +156,33 @@ class TasksController < ApplicationController
156
156
  redirect_to :action => :list, :id => task
157
157
  end
158
158
 
159
+ # Move the indicated task to the indicated position.
159
160
  def move_to
160
- task = Task.find(params[:id][5..-1])
161
- if params[:period_id] && params[:period_id].to_i != task.period_id
162
- task.remove_from_list
163
- task.period_id = params[:period_id]
161
+ params[:id] = $1 if params[:id] =~ /^task_(\d*)$/
162
+ if params[:id] && task = Task.find(params[:id])
163
+ if params[:target_id]
164
+ if target_task = Task.find_by_id(params[:target_id])
165
+ if task.parent_id != target_task.parent_id
166
+ task.remove_from_list
167
+ task.position = nil
168
+ task.parent_id = target_task.parent_id
169
+ task.backlog_id = target_task.backlog_id
170
+ task.period_id = target_task.period_id
171
+ end
172
+ task.insert_at target_task.position
173
+ end
174
+ elsif params[:period_id] && params[:period_id].to_i != task.period_id
175
+ task.remove_from_list
176
+ task.period_id = params[:period_id]
177
+ task.insert_at 1
178
+ task.save!
179
+ else
180
+ flash[:notice] = "Target position is missing for move."
181
+ end
182
+ else
183
+ flash[:notice] = "Task not found"
164
184
  end
165
- task.insert_at params[:position]
166
- back_or_redirect_to :controller => 'periods', :action => :show_no_layout, :id => task.period, :task => task.id
185
+ back_or_redirect_to :controller => 'periods', :action => :show_no_layout, :id => task.period_id, :task => task.id
167
186
  end
168
187
 
169
188
  def move_to_period(with_layout = false)
@@ -97,13 +97,13 @@ class WorksController < ApplicationController
97
97
 
98
98
  def weekly_work_sheet
99
99
  @week = (params[:id] && params[:id].to_i) || Date.today.cweek
100
- @rows = Work.works_for_week(@week, user)
100
+ @rows = Work.works_for_week(@week)
101
101
  render :layout => 'wide'
102
102
  end
103
103
 
104
104
  def timeliste
105
105
  @week = (params[:id] && params[:id].to_i) || Date.today.cweek
106
- @backlogs = Work.work_totals_for_week(@week, user_id)
106
+ @backlogs = Work.work_totals_for_week(@week)
107
107
  headers["Content-Type"] = "application/vnd.ms-excel"
108
108
  headers["Content-Disposition"] = 'attachment; filename="export.xml"'
109
109
  render :layout => false
data/app/models/work.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  class Work < ActiveRecord::Base
2
+ extend UserSystem
3
+ include UserSystem
4
+
2
5
  belongs_to :task
3
6
  belongs_to :user
4
7
 
@@ -22,13 +25,13 @@ class Work < ActiveRecord::Base
22
25
  # [m2, t2, nil,t2, nil,nil, nil],
23
26
  # [nil,t2, nil,nil,nil,nil, nil],
24
27
  # ]
25
- def self.works_for_week(week_no, user)
28
+ def self.works_for_week(week_no, user = current_user)
26
29
  first = Date.commercial(Date.today.year, week_no, 1)
27
30
  last = first + 7
28
31
  works = find(:all, :conditions => "completed_at BETWEEN '#{first.to_time.iso8601}' AND '#{last.to_time.iso8601}'", :order => 'completed_at')
29
32
  length = 0
30
33
  works_per_day = (0..6).map do |day|
31
- works_for_day = works.select {|work| work.completed_at.to_date == (first + day) && (!work.task.enable_users? || (user && work.user_id == user.id)) }
34
+ works_for_day = works.select {|work| work.completed_at.to_date == (first + day) && (work.user_id.nil? || (user && work.user_id == user.id)) }
32
35
  length = [length, works_for_day.length].max
33
36
  works_for_day
34
37
  end
@@ -41,7 +44,7 @@ class Work < ActiveRecord::Base
41
44
  # backlog1.id => [[m, t, w, t, f, s, s], [m, t, w, t, f, s, s]],
42
45
  # backlog2.id => [<work for monday>, 0, <work for wednesday>, <work for thursday>, <work for friday>, 0, <work for sunday>]
43
46
  # }
44
- def self.work_totals_for_week(week_no, user_id = nil)
47
+ def self.work_totals_for_week(week_no, user_id = current_user)
45
48
  first = Date.commercial(Date.today.year, week_no, 1)
46
49
  last = first + 7
47
50
  works = find(:all, :conditions => "completed_at BETWEEN '#{first.to_time.iso8601}' AND '#{last.to_time.iso8601}'", :order => 'completed_at')
@@ -49,7 +52,7 @@ class Work < ActiveRecord::Base
49
52
  Backlog.find(:all).each do |backlog|
50
53
  totals_per_backlog[backlog.id] = [[], []]
51
54
  (0..6).each do |day|
52
- works_for_day = works.select {|work| work.task.backlog == backlog && work.completed_at.to_date == (first + day) && (!work.task.backlog.enable_users || (user_id && work.user_id == user_id)) }
55
+ works_for_day = works.select {|work| (work.task.backlog == backlog) && (work.completed_at.to_date == (first + day)) && (user_id && work.user_id == user_id) }
53
56
  invoice_works_for_day = works_for_day.select {|work| work.invoice? }
54
57
  internal_works_for_day = works_for_day.select {|work| !work.invoice? }
55
58
 
@@ -94,7 +94,7 @@
94
94
  <% if active && (@task.period.nil? || @task.period.active_or_future?) %>
95
95
  <%=draggable_element "task_#{@task.id}" %>
96
96
  <%=drop_receiving_element "task_#{@task.id}",
97
- :update => update, :url => with_detour({:controller => 'tasks', :action => "move_to", :period_id => @task.period_id, :position => @task.position, :layout => false}),
97
+ :update => update, :url => with_detour({:controller => 'tasks', :action => "move_to", :target_id => @task.id, :layout => false}),
98
98
  :accept => "tasks",
99
99
  :loading => "",
100
100
  :complete => "",
@@ -56,7 +56,7 @@ end %>]
56
56
  <% week_total += @work.hours %>
57
57
  <td>
58
58
  <%=link_to(h(@work.task.period.name), :controller => 'periods', :action => :show, :id => @work.task.period) if @work.task.period %>
59
- <%=link_to(h(@work.task.backlog.name), :controller => 'backlogs', :action => :show, :id => @work.task.backlog) %>
59
+ <%=link_to(h(@work.task.root_task.backlog.name), :controller => 'backlogs', :action => :show, :id => @work.task.root_task.backlog) %>
60
60
  <%=link_to(h(@work.task.description), :controller => 'periods', :action => :show, :id => @work.task.period, :task_id => @work.task.id) %>
61
61
  </td>
62
62
  <% if invoicing %>
@@ -4,7 +4,15 @@ first:
4
4
  task_id: 1
5
5
  started_at: 2007-06-12T13:35:00
6
6
  completed_at: 2007-06-12T14:35:00
7
+ hours: 40.0
7
8
  started:
8
9
  id: 2
9
10
  task_id: 4
10
11
  started_at: 2007-06-12T13:35:00
12
+ personal:
13
+ id: 3
14
+ task_id: 1
15
+ started_at: 2007-06-12T13:35:00
16
+ completed_at: 2007-06-12T14:35:00
17
+ user_id: 1000001
18
+ hours: 40.0
@@ -172,6 +172,7 @@ class TasksControllerTest < Test::Unit::TestCase
172
172
 
173
173
  def test_end_work
174
174
  before = Task.find(1)
175
+ assert_equal 80, before.total_done
175
176
 
176
177
  post :end_work, :id => 1, :work => {:work_started_at_time => (Time.now - 3600).strftime('%H:%M')}
177
178
  assert_response :redirect
@@ -183,7 +184,23 @@ class TasksControllerTest < Test::Unit::TestCase
183
184
  'estimate[todo]' => 1
184
185
 
185
186
  after = Task.find(1)
186
- assert((after.total_done == BigDecimal('1')) || (after.total_done - 1 < 0.2))
187
+ assert_equal 80, after.total_done
188
+ end
189
+
190
+ def test_move_to__subtask_to_top
191
+ subtask = tasks(:subtask)
192
+ subtask_before = Task.find(subtask.id)
193
+ supertask = tasks(:supertask)
194
+ supertask_before = Task.find(supertask.id)
195
+
196
+ post :move_to, :id => subtask.id.to_s, :target_id => supertask.id.to_s
197
+
198
+ assert_response :redirect
199
+ assert_redirected_to :controller => 'periods', :action => :show_no_layout, :id => subtask_before.root_task.period_id
200
+
201
+ subtask_after = Task.find(subtask.id)
202
+ assert_equal subtask.root_task.period_id, subtask_after.period_id
203
+ assert_equal 3, subtask_after.position
187
204
  end
188
205
 
189
206
  def test_move_to_next_period
@@ -4,7 +4,7 @@ require 'user_notify'
4
4
 
5
5
  class UserSystemTest < ActionController::IntegrationTest
6
6
  self.use_transactional_fixtures = false
7
- fixtures :users, :groups_users
7
+ fixtures :users, :groups_users, :works
8
8
 
9
9
  def setup
10
10
  ActionMailer::Base.inject_one_error = false
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class UserTest < Test::Unit::TestCase
4
- fixtures :users, :groups_users
4
+ fixtures :users, :groups_users, :works
5
5
  self.use_transactional_fixtures = false
6
6
 
7
7
  def test_authenticate
@@ -2,9 +2,20 @@ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class WorkTest < Test::Unit::TestCase
4
4
  fixtures :works
5
-
6
- # Replace this with your real tests.
7
- def test_truth
8
- assert true
5
+
6
+ def test_work_totals_for_week
7
+ work_totals = Work.work_totals_for_week(24, 1000001)
8
+ assert_equal 1, work_totals.size
9
+ assert_equal Array, work_totals[1].class
10
+ assert_equal 2, work_totals[1].size
11
+ assert_equal Array, work_totals[1][0].class
12
+ assert_equal Array, work_totals[1][1].class
13
+ assert_equal 0, work_totals[1][1][0]
14
+ assert_equal 40, work_totals[1][1][1]
15
+ assert_equal 0, work_totals[1][1][2]
16
+ assert_equal 0, work_totals[1][1][3]
17
+ assert_equal 0, work_totals[1][1][4]
18
+ assert_equal 0, work_totals[1][1][5]
19
+ assert_equal 0, work_totals[1][1][6]
9
20
  end
10
21
  end
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: backlog
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.10.3
6
+ version: 0.10.4
7
7
  date: 2007-09-24 00:00:00 +02:00
8
8
  summary: Application to aid collecting, processing, organizing, reviewing and doing tasks.
9
9
  require_paths: