backlog 0.21.3 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +13 -0
- data/Rakefile +1 -1
- data/app/controllers/backlogs_controller.rb +7 -0
- data/app/controllers/work_locks_controller.rb +2 -2
- data/app/controllers/works_controller.rb +2 -1
- data/app/models/backlog.rb +1 -0
- data/app/models/report_filter.rb +15 -0
- data/app/models/work.rb +3 -2
- data/app/views/backlogs/_buttons.rhtml +1 -0
- data/app/views/works/list.rhtml +45 -0
- data/app/views/works/weekly_work_sheet_by_work_account.rhtml +1 -1
- data/test/fixtures/work_accounts.yml +2 -2
- data/test/fixtures/works.yml +1 -1
- data/test/functional/tasks_controller_test.rb +12 -2
- data/test/functional/work_accounts_controller_test.rb +1 -1
- data/test/unit/work_test.rb +36 -4
- metadata +3 -2
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== 0.22.0 2008-02-14
|
2
|
+
|
3
|
+
=== Features
|
4
|
+
|
5
|
+
* Added report for displaying all work records relating to tasks in a backlog for a given time period.
|
6
|
+
* Aded ability to look at other users weekly work sheets.
|
7
|
+
Used in the Work Lock Notification mail.
|
8
|
+
|
9
|
+
=== Fixes
|
10
|
+
|
11
|
+
* Fixed filtering of other users work records in weekly work sheet.
|
12
|
+
* Changed to display full name instead of login in weekly work sheet.
|
13
|
+
|
1
14
|
== 0.21.3 2008-02-13
|
2
15
|
|
3
16
|
=== Features
|
data/Rakefile
CHANGED
@@ -34,7 +34,7 @@ Hoe.new("backlog", APP::VERSION) do |p|
|
|
34
34
|
p.url = 'http://rubyforge.org/projects/backlog/'
|
35
35
|
p.extra_deps = [['rails', '>= 1.2.4'], ['gruff', '>= 0.2.9'], ['rmagick', '= 1.15.12'],
|
36
36
|
['postgres', '>= 0.7.9'], ['slave', '>= 1.2.1']]
|
37
|
-
p.rsync_args = "-
|
37
|
+
p.rsync_args = "-acv --delete --exclude=wiki*"
|
38
38
|
end
|
39
39
|
|
40
40
|
desc 'Release the application to RubyForge'
|
@@ -174,6 +174,13 @@ class BacklogsController < ApplicationController
|
|
174
174
|
render :text => 'alert("Updated sort order");'
|
175
175
|
end
|
176
176
|
|
177
|
+
def works
|
178
|
+
backlog = Backlog.find(params[:id])
|
179
|
+
@report_filter = ReportFilter.new(params[:report_filter])
|
180
|
+
@works = Work.paginate :conditions => ["completed_at BETWEEN ? AND ? AND task_id IN (SELECT id FROM tasks t where t.backlog_id = ?)", @report_filter.start_on, @report_filter.end_on, backlog.id], :page => params[:page]
|
181
|
+
render :template => '/works/list'
|
182
|
+
end
|
183
|
+
|
177
184
|
private
|
178
185
|
|
179
186
|
def load_tasks(backlog)
|
@@ -61,8 +61,8 @@ class WorkLocksController < ApplicationController
|
|
61
61
|
user_subscribers = current_user.work_lock_subscribers
|
62
62
|
notify_users = (work_account_subscribers + user_subscribers).uniq
|
63
63
|
notify_users.each do |user|
|
64
|
-
week_url = url_for :controller => 'works', :action => :weekly_work_sheet_by_work_account, :year => @year, :week => @week
|
65
|
-
spreadsheet_url = url_for :controller => 'works', :action => :timeliste, :year => @year, :week => @week
|
64
|
+
week_url = url_for :controller => 'works', :action => :weekly_work_sheet_by_work_account, :year => @year, :week => @week, :user_id => current_user.id
|
65
|
+
spreadsheet_url = url_for :controller => 'works', :action => :timeliste, :year => @year, :week => @week, :user_id => current_user.id
|
66
66
|
WorkLockNotify.deliver_lock(user, current_user, @week, week_url, spreadsheet_url)
|
67
67
|
end
|
68
68
|
back_or_redirect_to :controller => 'works', :action => :weekly_work_sheet, :year => @year, :week => @week
|
@@ -156,7 +156,8 @@ class WorksController < ApplicationController
|
|
156
156
|
def weekly_work_sheet_by_work_account
|
157
157
|
@year = (params[:year] && params[:year].to_i) || Date.today.year
|
158
158
|
@week = (params[:week] && params[:week].to_i) || Date.today.cweek
|
159
|
-
@
|
159
|
+
@user = params[:user_id] ? User.find(params[:user_id]) : current_user
|
160
|
+
@work_accounts = Work.works_for_week_by_work_account(@year, @week, @user)
|
160
161
|
@first_date = Date.commercial(@year, @week, 1)
|
161
162
|
@last_date = @first_date + 6
|
162
163
|
@lock = WorkLock.find(:first, :conditions => ['user_id = ? AND start_on <= ? AND end_on >= ?', current_user.id, @first_date, @last_date])
|
data/app/models/backlog.rb
CHANGED
@@ -8,6 +8,7 @@ class Backlog < ActiveRecord::Base
|
|
8
8
|
validates_inclusion_of :enable_users, :in => [true, false], :allow_nil => true, :message => ActiveRecord::Errors.default_error_messages[:blank]
|
9
9
|
|
10
10
|
belongs_to :work_account
|
11
|
+
belongs_to :customer
|
11
12
|
has_many :tasks, :order => 'period_id, position', :dependent => :destroy
|
12
13
|
has_many :unplanned_tasks, :class_name => 'Task', :conditions => 'period_id IS NULL', :order => 'position'
|
13
14
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ReportFilter
|
2
|
+
attr_reader :start_on
|
3
|
+
attr_reader :end_on
|
4
|
+
|
5
|
+
def initialize(attributes)
|
6
|
+
if attributes
|
7
|
+
attributes = attributes.clone
|
8
|
+
@start_on = Date.parse attributes.delete(:start_on) || Date.local(2007, 01, 01)
|
9
|
+
end_on_param = attributes.delete(:end_on)
|
10
|
+
@end_on = end_on_param && end_on_param.size > 0 ? Date.parse(end_on_param) : Date.today
|
11
|
+
raise "Unknown parameters: #{attributes.inspect}" unless attributes.empty?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/app/models/work.rb
CHANGED
@@ -5,6 +5,7 @@ class Work < ActiveRecord::Base
|
|
5
5
|
belongs_to :task
|
6
6
|
belongs_to :user
|
7
7
|
belongs_to :work_account
|
8
|
+
belongs_to :customer
|
8
9
|
|
9
10
|
validates_associated :task
|
10
11
|
validates_presence_of :work_account
|
@@ -53,7 +54,7 @@ class Work < ActiveRecord::Base
|
|
53
54
|
def self.works_for_week_by_work_account(year, week_no, user = current_user)
|
54
55
|
first_date = Date.commercial(year, week_no, 1)
|
55
56
|
last_date = first_date + 6
|
56
|
-
works = find(:all, :conditions => "completed_at IS NOT NULL AND completed_at BETWEEN '#{first_date.to_time.iso8601}' AND '#{(last_date+1).to_time.iso8601}'", :order => 'completed_at, started_at')
|
57
|
+
works = find(:all, :conditions => "user_id #{user ? " = #{user.id}" : "IS NULL"} AND completed_at IS NOT NULL AND completed_at BETWEEN '#{first_date.to_time.iso8601}' AND '#{(last_date+1).to_time.iso8601}'", :order => 'completed_at, started_at')
|
57
58
|
result = {}
|
58
59
|
works.each do |work|
|
59
60
|
day_of_week = work.completed_at.to_date.cwday - 1
|
@@ -79,7 +80,7 @@ class Work < ActiveRecord::Base
|
|
79
80
|
works.map{|w| w.work_account}.uniq.each do |work_account|
|
80
81
|
totals_per_work_account[work_account.id] = [[], []]
|
81
82
|
(0..6).each do |day|
|
82
|
-
works_for_day = works.select {|work| (work.work_account == work_account) && (work.completed_at.to_date == (first + day)) && (work.user_id.nil? || (user && work.user_id == user.id)) }
|
83
|
+
works_for_day = works.select {|work| (work.work_account == work_account) && (work.completed_at.to_date == (first + day)) && ((user.nil? && work.user_id.nil?) || (user && work.user_id == user.id)) }
|
83
84
|
invoice_works_for_day = works_for_day.select {|work| work.invoice? }
|
84
85
|
internal_works_for_day = works_for_day.select {|work| !work.invoice? }
|
85
86
|
|
@@ -1,3 +1,4 @@
|
|
1
1
|
<%=image_link_to 'arrow_up.png', l(:backlogs), :action => :list %>
|
2
2
|
<%=image_detour_to('clipboard.png', l(:edit), :controller => 'backlogs', :action => :edit, :id => @backlog) unless controller.action_name == 'edit' %>
|
3
|
+
<%=image_detour_to('hammer.png', l(:work), :controller => 'backlogs', :action => :works, :id => @backlog) %>
|
3
4
|
<%=detour_to(image_tag(url_for("add.png"), :alt => l(:add_task), :title => l(:add_task), :class => 'image-submit'), :controller => 'tasks', :action => 'new', :task => {:backlog_id => @backlog.id} ) %>
|
data/app/views/works/list.rhtml
CHANGED
@@ -3,6 +3,51 @@
|
|
3
3
|
<% if @period %>
|
4
4
|
<%=render :partial => '/periods/title' %>
|
5
5
|
<% end %>
|
6
|
+
|
7
|
+
<% if @report_filter %>
|
8
|
+
<% form_for :report_filter do |f| %>
|
9
|
+
<p><label for="report_filter_start_on"><%=l :start_on%></label>
|
10
|
+
<%=f.text_field 'start_on', :size => 16, :value => @report_filter.start_on ? @report_filter.start_on.strftime('%Y-%m-%d') : nil %>
|
11
|
+
<button id="trigger1">...</button>
|
12
|
+
<script type="text/javascript">//<![CDATA[
|
13
|
+
Zapatec.Calendar.setup({
|
14
|
+
firstDay : 1,
|
15
|
+
showOthers : true,
|
16
|
+
showsTime : true,
|
17
|
+
step : 1,
|
18
|
+
electric : false,
|
19
|
+
inputField : "report_filter_start_on",
|
20
|
+
button : "trigger1",
|
21
|
+
ifFormat : "%Y-%m-%d",
|
22
|
+
daFormat : "%Y/%m/%d",
|
23
|
+
timeInterval : 15
|
24
|
+
});
|
25
|
+
//]]></script>
|
26
|
+
|
27
|
+
<label for="report_filter_end_on"><%=l :completed_at%></label>
|
28
|
+
<%=f.text_field 'end_on', :size => 16, :value => (@report_filter.end_on && @report_filter.end_on.strftime('%Y-%m-%d')) %>
|
29
|
+
<button id="trigger2">...</button>
|
30
|
+
<script type="text/javascript">//<![CDATA[
|
31
|
+
Zapatec.Calendar.setup({
|
32
|
+
firstDay : 1,
|
33
|
+
showOthers : true,
|
34
|
+
showsTime : true,
|
35
|
+
step : 1,
|
36
|
+
electric : false,
|
37
|
+
inputField : "report_filter_end_on",
|
38
|
+
button : "trigger2",
|
39
|
+
ifFormat : "%Y-%m-%d",
|
40
|
+
daFormat : "%Y/%m/%d",
|
41
|
+
timeInterval : 15
|
42
|
+
});
|
43
|
+
//]]></script>
|
44
|
+
<%=submit_tag l(:search) %>
|
45
|
+
</p>
|
46
|
+
|
47
|
+
<% end %>
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
|
6
51
|
<table>
|
7
52
|
<tr>
|
8
53
|
<th><%=l :task %></th>
|
data/test/fixtures/works.yml
CHANGED
@@ -175,7 +175,7 @@ class TasksControllerTest < Test::Unit::TestCase
|
|
175
175
|
|
176
176
|
def test_end_work
|
177
177
|
before = Task.find(1)
|
178
|
-
assert_equal
|
178
|
+
assert_equal 70, before.total_done
|
179
179
|
|
180
180
|
post :end_work, :id => 1, :work => {:work_started_at_time => (Time.now - 3600).strftime('%H:%M')}
|
181
181
|
assert_response :redirect
|
@@ -187,7 +187,7 @@ class TasksControllerTest < Test::Unit::TestCase
|
|
187
187
|
'estimate[todo]' => 1
|
188
188
|
|
189
189
|
after = Task.find(1)
|
190
|
-
assert_equal
|
190
|
+
assert_equal 70, after.total_done
|
191
191
|
end
|
192
192
|
|
193
193
|
def test_move_to__subtask_to_top
|
@@ -215,4 +215,14 @@ class TasksControllerTest < Test::Unit::TestCase
|
|
215
215
|
assert after.work_started?
|
216
216
|
end
|
217
217
|
|
218
|
+
def test_start_work_xhr
|
219
|
+
# raise "This test fails alone, but not with other tests..."
|
220
|
+
task_id = tasks(:first).id
|
221
|
+
|
222
|
+
xhr :post, :start_work, :id => task_id
|
223
|
+
|
224
|
+
after = Task.find(task_id)
|
225
|
+
assert after.work_started?
|
226
|
+
end
|
227
|
+
|
218
228
|
end
|
@@ -13,7 +13,7 @@ class WorkAccountsControllerTest < Test::Unit::TestCase
|
|
13
13
|
@response = ActionController::TestResponse.new
|
14
14
|
@request.session[:user_id] = 1000001
|
15
15
|
|
16
|
-
@first_id = work_accounts(:
|
16
|
+
@first_id = work_accounts(:light_control).id
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_index
|
data/test/unit/work_test.rb
CHANGED
@@ -5,10 +5,15 @@ class WorkTest < Test::Unit::TestCase
|
|
5
5
|
include UserSystem
|
6
6
|
|
7
7
|
main_scenario
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
Thread.current[:user] = nil
|
11
|
+
end
|
8
12
|
|
9
13
|
def test_work_totals_for_week
|
14
|
+
Thread.current[:user] = users(:tesla)
|
10
15
|
# Week 24 is from
|
11
|
-
work_totals = Work.work_totals_for_week(2007, 24,
|
16
|
+
work_totals = Work.work_totals_for_week(2007, 24, users(:tesla))
|
12
17
|
assert_equal 1, work_totals.size
|
13
18
|
assert_equal Array, work_totals[1].class
|
14
19
|
assert_equal 2, work_totals[1].size
|
@@ -16,6 +21,23 @@ class WorkTest < Test::Unit::TestCase
|
|
16
21
|
assert_equal Array, work_totals[1][1].class
|
17
22
|
assert_equal 0, work_totals[1][1][0]
|
18
23
|
assert_equal 40, work_totals[1][1][1]
|
24
|
+
assert_equal 8, work_totals[1][1][2]
|
25
|
+
assert_equal 0, work_totals[1][1][3]
|
26
|
+
assert_equal 0, work_totals[1][1][4]
|
27
|
+
assert_equal 0, work_totals[1][1][5]
|
28
|
+
assert_equal 0, work_totals[1][1][6]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_work_totals_for_week_anonymously
|
32
|
+
# Week 24 is from
|
33
|
+
work_totals = Work.work_totals_for_week(2007, 24, nil)
|
34
|
+
assert_equal 1, work_totals.size
|
35
|
+
assert_equal Array, work_totals[1].class
|
36
|
+
assert_equal 2, work_totals[1].size
|
37
|
+
assert_equal Array, work_totals[1][0].class
|
38
|
+
assert_equal Array, work_totals[1][1].class
|
39
|
+
assert_equal 0, work_totals[1][1][0]
|
40
|
+
assert_equal 30, work_totals[1][1][1]
|
19
41
|
assert_equal 0, work_totals[1][1][2]
|
20
42
|
assert_equal 0, work_totals[1][1][3]
|
21
43
|
assert_equal 0, work_totals[1][1][4]
|
@@ -27,14 +49,24 @@ class WorkTest < Test::Unit::TestCase
|
|
27
49
|
Thread.current[:user] = users(:tesla)
|
28
50
|
assert_equal 1, Work.find_work_for_day(Date.parse('2007-06-12')).size
|
29
51
|
end
|
30
|
-
|
52
|
+
|
53
|
+
def test_works_for_week_by_work_account
|
54
|
+
Thread.current[:user] = users(:tesla)
|
55
|
+
work_totals = Work.works_for_week_by_work_account(2007, 24, users(:tesla))
|
56
|
+
assert_equal({work_accounts(:light_control) => [nil, BigDecimal('40'), BigDecimal('8'), nil, nil, nil, nil]}, work_totals)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_works_for_week_by_work_account_anonymous
|
60
|
+
work_totals = Work.works_for_week_by_work_account(2007, 24, nil)
|
61
|
+
assert_equal({work_accounts(:light_control) => [nil, BigDecimal('30'), nil, nil, nil, nil, nil]}, work_totals)
|
62
|
+
end
|
63
|
+
|
31
64
|
private
|
32
65
|
|
33
66
|
# TODO (uwe): This method should be removed
|
34
67
|
# It is here only because ClassTableInheritanceInRails broke reading fixtures by name
|
35
68
|
def users(login)
|
36
69
|
super(login)
|
37
|
-
end
|
38
|
-
|
70
|
+
end
|
39
71
|
|
40
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uwe Kubosch
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-14 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -246,6 +246,7 @@ files:
|
|
246
246
|
- app/models/user.rb
|
247
247
|
- app/models/configuration.rb
|
248
248
|
- app/models/chart.rb
|
249
|
+
- app/models/report_filter.rb
|
249
250
|
- app/models/group.rb
|
250
251
|
- app/models/work_lock_subscription.rb
|
251
252
|
- app/models/backlog.rb
|