backlog 0.23.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/History.txt +17 -4
  2. data/app/controllers/absences_controller.rb +64 -0
  3. data/app/controllers/periods_controller.rb +1 -1
  4. data/app/controllers/tasks_controller.rb +6 -4
  5. data/app/controllers/user_controller.rb +7 -0
  6. data/app/controllers/works_controller.rb +21 -16
  7. data/app/helpers/absences_helper.rb +2 -0
  8. data/app/models/absence.rb +14 -0
  9. data/app/models/task.rb +3 -2
  10. data/app/models/work.rb +33 -21
  11. data/app/views/absences/_form.rhtml +10 -0
  12. data/app/views/absences/edit.rhtml +9 -0
  13. data/app/views/absences/list.rhtml +27 -0
  14. data/app/views/absences/new.rhtml +8 -0
  15. data/app/views/absences/show.rhtml +8 -0
  16. data/app/views/layouts/absences.rhtml +17 -0
  17. data/app/views/tasks/_task.rhtml +1 -1
  18. data/app/views/tasks/edit.rhtml +1 -1
  19. data/app/views/user/edit.rhtml +36 -1
  20. data/app/views/works/_row.rhtml +19 -5
  21. data/app/views/works/_row_field.rhtml +14 -3
  22. data/app/views/works/daily_work_sheet.rhtml +81 -12
  23. data/app/views/works/list_excel.rhtml +1 -1
  24. data/app/views/works/timeliste.rhtml +3 -3
  25. data/app/views/works/update_row.rjs +3 -1
  26. data/app/views/works/update_time.rjs +2 -2
  27. data/app/views/works/weekly_work_sheet.rhtml +3 -3
  28. data/db/migrate/028_create_absences.rb +34 -0
  29. data/db/schema.rb +11 -2
  30. data/lang/en.yaml +4 -0
  31. data/lang/no.yaml +4 -0
  32. data/lib/change_column_null_migration_fix.rb +2 -0
  33. data/test/fixtures/absences.yml +11 -0
  34. data/test/fixtures/works.yml +10 -5
  35. data/test/functional/absences_controller_test.rb +93 -0
  36. data/test/functional/tasks_controller_test.rb +3 -2
  37. data/test/functional/works_controller_test.rb +33 -6
  38. data/test/test_helper.rb +3 -2
  39. data/test/unit/absence_test.rb +31 -0
  40. data/test/unit/work_test.rb +7 -0
  41. data/vendor/plugins/rails_time/MIT-LICENSE +20 -0
  42. data/vendor/plugins/rails_time/README +28 -0
  43. data/vendor/plugins/rails_time/init.rb +2 -0
  44. data/vendor/plugins/rails_time/lib/activerecord_time_extension.rb +28 -0
  45. data/vendor/plugins/rails_time/lib/time_of_day.rb +81 -0
  46. data/vendor/plugins/rails_time/test/database.yml +18 -0
  47. data/vendor/plugins/rails_time/test/rails_time_test.rb +122 -0
  48. data/vendor/plugins/rails_time/test/schema.rb +10 -0
  49. data/vendor/plugins/rails_time/test/test_helper.rb +17 -0
  50. metadata +28 -3
  51. data/app/views/works/daily_work_sheet_old.rhtml +0 -93
@@ -0,0 +1,81 @@
1
+ class TimeOfDay
2
+ yaml_as "tag:yaml.org,2002:timestamp#hms"
3
+ yaml_as "tag:yaml.org,2002:time"
4
+ yaml_as "tag:ruby.yaml.org,2002:time"
5
+
6
+ attr_accessor :hour; # 0 ‑ 23
7
+ attr_accessor :minute; # 0 ‑ 59
8
+ attr_accessor :second; # 0 ‑ 59
9
+
10
+ def initialize(hour, minute, second = 0)
11
+ raise "Invalid hour: #{hour}" unless hour >= 0 && hour <= 23
12
+ raise "Invalid minute: #{minute}" unless minute >= 0 && hour <= 59
13
+ raise "Invalid second: #{second}" unless second >= 0 && hour <= 59
14
+ @hour, @minute, @second = hour, minute, second
15
+ end
16
+
17
+ def self.now
18
+ Time.now.time_of_day
19
+ end
20
+
21
+ def self.parse(string)
22
+ raise "Illegal time format: '#{string}'" unless string =~ /(\d{1,2}):?(\d{2})(?::(\d{1,2}))?/
23
+ self.new($1.to_i, $2.to_i, $3.to_i)
24
+ end
25
+
26
+ def on(date)
27
+ Time.local(date.year, date.month, date.day, hour, minute, second)
28
+ end
29
+
30
+ def -(seconds)
31
+ raise "Illegal argument: #{seconds.inspect}" unless seconds.is_a? Numeric
32
+ t = Time.local(0,1,1, hour, minute, second)
33
+ t -= seconds
34
+ self.class.new(t.hour, t.min, t.sec)
35
+ end
36
+
37
+ def ==(other)
38
+ (self <=> other) == 0
39
+ end
40
+
41
+ def <=>(other)
42
+ [@hour, @minute, @second] <=> [other.hour, other.minute, other.second]
43
+ end
44
+
45
+ def strftime(format)
46
+ on(Date.today).strftime(format)
47
+ end
48
+
49
+ def to_s
50
+ "%02d:%02d:%02d" % [@hour, @minute, @second]
51
+ end
52
+
53
+ def self.yaml_new( klass, tag, val )
54
+ if String === val
55
+ self.parse val
56
+ else
57
+ raise YAML::TypeError, "Invalid Time: " + val.inspect
58
+ end
59
+ end
60
+
61
+ def to_yaml( opts = {} )
62
+ YAML::quick_emit( nil, opts ) do |out|
63
+ out.scalar( 'tag:yaml.org,2002:time', self.to_s, :plain )
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ class Time
70
+ def time_of_day
71
+ TimeOfDay.new(hour, min, sec)
72
+ end
73
+
74
+ end
75
+
76
+ class Date
77
+ def at(time_of_day)
78
+ Time.local(year, month, day, time_of_day.hour, time_of_day.minute, time_of_day.second)
79
+ end
80
+
81
+ end
@@ -0,0 +1,18 @@
1
+ sqlite:
2
+ :adapter: sqlite
3
+ :dbfile: plugin.sqlite.db
4
+ sqlite3:
5
+ :adapter: sqlite3
6
+ :dbfile: ":memory:"
7
+ postgresql:
8
+ :adapter: postgresql
9
+ :username: postgres
10
+ :password: postgres
11
+ :database: plugin_test
12
+ :min_messages: ERROR
13
+ mysql:
14
+ :adapter: mysql
15
+ :host: localhost
16
+ :username: rails
17
+ :password:
18
+ :database: plugin_test
@@ -0,0 +1,122 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Thing < ActiveRecord::Base
4
+ end
5
+
6
+ def thing
7
+ Thing.new(:name => "Thing One",:price_in_cents=> 125)
8
+ end
9
+
10
+ class RailsMoneyTest < Test::Unit::TestCase
11
+
12
+ def test_should_return_price_as_money_object
13
+ price = thing.price
14
+ assert_kind_of Money, price
15
+ assert_equal "$1.25", thing.price.to_s
16
+ end
17
+
18
+ def test_should_set_price_from_money_object
19
+ thing1 = thing
20
+ thing1.price = Money.new(1095)
21
+ assert_equal 109500, thing1.price_in_cents
22
+ assert_equal "$1,095.00", thing1.price.to_s
23
+ end
24
+
25
+ def test_should_set_price_from_fixnum
26
+ thing1 = thing
27
+ thing1.price = 1095
28
+ assert_equal 109500, thing1.price_in_cents
29
+ end
30
+
31
+ def test_should_set_price_from_float
32
+ thing1 = thing
33
+ thing1.price = 10.95
34
+ assert_equal 1095, thing1.price_in_cents
35
+ end
36
+
37
+ def test_should_set_price_from_string
38
+ thing1 = thing
39
+ thing1.price = "$10.95"
40
+ assert_equal 1095, thing1.price_in_cents
41
+ thing1.price = "10"
42
+ assert_equal 1000, thing1.price_in_cents
43
+ end
44
+
45
+ def test_should_format_correctly
46
+ assert_equal "$12.40", Money.new(12.40).to_s
47
+ end
48
+
49
+ def test_should_raise_exception_setting_invalid_price
50
+ assert_raise(MoneyError) { thing.price = [] }
51
+ end
52
+ end
53
+
54
+ class MoneyTest < Test::Unit::TestCase
55
+
56
+ def test_should_create_money_object
57
+ assert cash_money = Money.new(1290)
58
+ assert_equal 129000, cash_money.cents
59
+ assert_equal 1290, cash_money.dollars
60
+ assert_equal "$1,290.00", cash_money.to_s
61
+ assert_equal false, cash_money.free?
62
+ assert_equal 0, Money.new(nil).cents
63
+ end
64
+
65
+ def test_should_create_money_object_from_float_with_proper_rounding
66
+ money = Money.new(12.196)
67
+ assert_equal 1220, money.cents
68
+ assert_instance_of Fixnum, money.cents
69
+ end
70
+
71
+ def test_should_raise_exception_if_invalid_type_passed_to_initialize
72
+ assert_raise(MoneyError) { Money.new([]) }
73
+ end
74
+
75
+ def test_should_return_free_on_to_s_if_cents_is_zero
76
+ cash_money = Money.new(0)
77
+ assert_equal 'free', cash_money.to_s
78
+ assert_equal true, cash_money.free?
79
+ assert_equal true, cash_money.zero?
80
+ end
81
+
82
+ def test_should_be_comparable
83
+ assert Money.include?(Comparable)
84
+ assert Money.new(0) == Money.new(0)
85
+ end
86
+
87
+ def test_should_add_money
88
+ assert_equal Money.new(20.95), Money.new(10) + Money.new(10.95)
89
+ assert_equal Money.new(2000), Money.new(1000) + 1000
90
+ assert_equal Money.new(20.06), Money.new(10.00) + 10.056
91
+ end
92
+
93
+ def test_should_subtract_money
94
+ assert_equal Money.new(500), Money.new(1000) - Money.new(500)
95
+ assert_equal Money.new(500), Money.new(1000) - 500
96
+ assert_equal Money.new(4.60), Money.new(10) - 5.40
97
+ end
98
+
99
+ def test_should_multiply_money
100
+ assert_equal Money.new(500), Money.new(100) * 5
101
+ assert_equal Money.new(9.99), Money.new(3.33) * 3
102
+ assert_equal Money.new(11.99), Money.new(3.33) * 3.6 # 1198.9
103
+ end
104
+
105
+ def test_should_divide_money_and_retur_array_of_monies
106
+ money_array = [Money.new(3.34), Money.new(3.33), Money.new(3.33)]
107
+ assert_equal money_array, Money.new(10.00) / 3
108
+ assert_equal [Money.new(2.00), Money.new(2.00)], Money.new(4.00) / 2
109
+ assert_raises(MoneyError) { Money.new(4.00) / 2.2 }
110
+ end
111
+
112
+ def test_should_implement_to_money
113
+ assert_equal Money.new(10), Money.new(10).to_money
114
+ assert_equal Money.new(100.00), 100.00.to_money
115
+ assert_equal Money.new(100.96), 100.956.to_money
116
+ end
117
+
118
+ def test_should_create_from_cents
119
+ assert_equal Money.new(1.50), Money.create_from_cents(150)
120
+ end
121
+
122
+ end
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ # Create tables for testing your plugin
4
+
5
+ create_table :things do |t|
6
+ t.column :name, :string
7
+ t.column :price_in_cents, :integer
8
+ end
9
+
10
+ end
@@ -0,0 +1,17 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ RAILS_ROOT = File.dirname(__FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'active_record'
7
+ require "#{File.dirname(__FILE__)}/../init"
8
+
9
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
10
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
11
+ ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
12
+
13
+ load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
14
+
15
+
16
+
17
+
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.23.1
4
+ version: 0.24.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-26 00:00:00 +01:00
12
+ date: 2008-02-29 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -115,6 +115,12 @@ files:
115
115
  - app/views/work_locks/edit.rhtml
116
116
  - app/views/work_locks/_form.rhtml
117
117
  - app/views/work_locks/show.rhtml
118
+ - app/views/absences
119
+ - app/views/absences/new.rhtml
120
+ - app/views/absences/list.rhtml
121
+ - app/views/absences/edit.rhtml
122
+ - app/views/absences/_form.rhtml
123
+ - app/views/absences/show.rhtml
118
124
  - app/views/work_accounts
119
125
  - app/views/work_accounts/new.rhtml
120
126
  - app/views/work_accounts/_title.rhtml
@@ -150,7 +156,6 @@ files:
150
156
  - app/views/works/list.rhtml
151
157
  - app/views/works/_row.rhtml
152
158
  - app/views/works/list_excel.rhtml
153
- - app/views/works/daily_work_sheet_old.rhtml
154
159
  - app/views/works/_buttons.rhtml
155
160
  - app/views/works/timeliste.rhtml
156
161
  - app/views/works/_description_list.rhtml
@@ -164,6 +169,7 @@ files:
164
169
  - app/views/works/weekly_work_sheet_by_work_account.rhtml
165
170
  - app/views/layouts
166
171
  - app/views/layouts/wide.rhtml
172
+ - app/views/layouts/absences.rhtml
167
173
  - app/views/layouts/mwrt002.rhtml
168
174
  - app/views/layouts/_headers.rhtml
169
175
  - app/views/layouts/_left_top.rhtml
@@ -221,6 +227,7 @@ files:
221
227
  - app/controllers/work_accounts_controller.rb
222
228
  - app/controllers/task_files_controller.rb
223
229
  - app/controllers/tasks_controller.rb
230
+ - app/controllers/absences_controller.rb
224
231
  - app/helpers
225
232
  - app/helpers/estimates_helper.rb
226
233
  - app/helpers/application_helper.rb
@@ -237,6 +244,7 @@ files:
237
244
  - app/helpers/parties_helper.rb
238
245
  - app/helpers/periods_helper.rb
239
246
  - app/helpers/search_helper.rb
247
+ - app/helpers/absences_helper.rb
240
248
  - app/models
241
249
  - app/models/work_lock_notify.rb
242
250
  - app/models/work.rb
@@ -246,6 +254,7 @@ files:
246
254
  - app/models/task.rb
247
255
  - app/models/user_notify.rb
248
256
  - app/models/search_result.rb
257
+ - app/models/absence.rb
249
258
  - app/models/estimate.rb
250
259
  - app/models/user.rb
251
260
  - app/models/configuration.rb
@@ -281,6 +290,7 @@ files:
281
290
  - test/unit/task_test.rb
282
291
  - test/unit/configuration_test.rb
283
292
  - test/unit/task_file_test.rb
293
+ - test/unit/absence_test.rb
284
294
  - test/unit/work_lock_test.rb
285
295
  - test/unit/work_test.rb
286
296
  - test/unit/user_test.rb
@@ -302,6 +312,7 @@ files:
302
312
  - test/functional/tasks_controller_test.rb
303
313
  - test/functional/welcome_controller_test.rb
304
314
  - test/functional/parties_controller_test.rb
315
+ - test/functional/absences_controller_test.rb
305
316
  - test/functional/user_controller_test.rb
306
317
  - test/functional/backlogs_controller_test.rb
307
318
  - test/functional/work_locks_controller_test.rb
@@ -337,6 +348,7 @@ files:
337
348
  - test/fixtures/users.yml
338
349
  - test/fixtures/customers.yml
339
350
  - test/fixtures/tasks.yml
351
+ - test/fixtures/absences.yml
340
352
  - test/performance
341
353
  - test/performance/server_test.rb
342
354
  - test/performance/common.rb
@@ -468,6 +480,18 @@ files:
468
480
  - vendor/plugins/will_paginate/lib/will_paginate/view_helpers.rb
469
481
  - vendor/plugins/will_paginate/lib/will_paginate/core_ext.rb
470
482
  - vendor/plugins/will_paginate/lib/will_paginate/collection.rb
483
+ - vendor/plugins/rails_time
484
+ - vendor/plugins/rails_time/README
485
+ - vendor/plugins/rails_time/init.rb
486
+ - vendor/plugins/rails_time/MIT-LICENSE
487
+ - vendor/plugins/rails_time/test
488
+ - vendor/plugins/rails_time/test/database.yml
489
+ - vendor/plugins/rails_time/test/rails_time_test.rb
490
+ - vendor/plugins/rails_time/test/schema.rb
491
+ - vendor/plugins/rails_time/test/test_helper.rb
492
+ - vendor/plugins/rails_time/lib
493
+ - vendor/plugins/rails_time/lib/time_of_day.rb
494
+ - vendor/plugins/rails_time/lib/activerecord_time_extension.rb
471
495
  - public
472
496
  - "public/Frav\xC3\xA6rsskjema.xls"
473
497
  - public/robots.txt
@@ -647,6 +671,7 @@ files:
647
671
  - db/migrate/020_create_task_files.rb
648
672
  - db/migrate/027_create_work_locks.rb
649
673
  - db/migrate/015_add_user_option.rb
674
+ - db/migrate/028_create_absences.rb
650
675
  - db/migrate/019_remove_unique_index_for_period_position.rb
651
676
  - db/migrate/021_create_work_accounts.rb
652
677
  - db/migrate/014_add_customer_option.rb
@@ -1,93 +0,0 @@
1
- <% @page_title = "#{l :experimental} #{l :daily_work_sheet} on #{@date}" + (" for #{user.login}" if user?) %>
2
-
3
- <div id="spotlight">
4
-
5
- <div style="float: left"><%=image_link_to('arrow_left.png', l(:previous_week), {:id => @date - 7}, :class => nil)%></div>
6
- <div style="float: left"><%=image_link_to('arrow_left.png', l(:previous_day), {:id => @date-1}, :class => nil)%></div>
7
- <div style="float: right"><%=image_link_to('arrow_right.png', l(:next_week), {:id => @date + 7}, :class => nil)%></div>
8
- <div style="float: right"><%=image_link_to('arrow_right.png', l(:next_day), {:id => @date+1}, :class => nil)%></div>
9
-
10
- <br clear="all" />
11
-
12
- <table sstyle="width: 100%" border="0">
13
- <tr>
14
- <th align="right" colspan="5">
15
- <%=link_to l(:weekly_work_sheet), :action => :weekly_work_sheet_by_work_account%>
16
- </th>
17
- </tr>
18
-
19
- <tr>
20
- <th><%=l :account %></th>
21
- <th><%=l :description %></th>
22
- <th><%=l :started_at %></th>
23
- <th><%=l :completed_at %></th>
24
- <th><%=l :done %></th>
25
- <th/>
26
- </tr>
27
-
28
- <% day_total = 0 %>
29
- <% for @work in @works %>
30
- <% day_total += @work.hours if @work %>
31
- <%=render :partial => 'row'%>
32
- <% end %>
33
- <% last_work = @work %>
34
- <% @work = nil %>
35
-
36
- <% if last_work.completed_at %>
37
- <% form_tag with_detour(:controller => 'works', :action => 'create') do %>
38
- <%=submit_tag('checkmark', :value => l(:save), :style => 'display: none')%>
39
- <%=hidden_field :work, :completed_at, :value => @date %>
40
-
41
- <tr>
42
- <td valign="bottom">
43
- <%=text_field_with_auto_complete :work, :work_account_name, {:value => '', :size => 16, :class => :task_description} %>
44
- </td>
45
- <td valign="bottom">
46
- <%=text_field_with_auto_complete :work, :description, {:size => 16, :class => :task_description} %>
47
- </td>
48
- <td align="right" valign="bottom">
49
- <%=text_field :work, :started_at_time, :value => last_work && last_work.completed_at.strftime('%H:%M'), :class => 'task_time' %>
50
- </td>
51
- <td align="right" valign="bottom">
52
- <%=text_field :work, :completed_at_time, :class => 'task_time', :value => @work && @work.completed_at.strftime('%H:%M') %>
53
- </td>
54
- <td align="right" valign="bottom">
55
- <%=text_field :work, :hours_time, :value => '', :class => 'task_hours' %>
56
- </td>
57
- <td valign="bottom">
58
- </td>
59
- </tr>
60
- <tr>
61
- <td/>
62
- <th><%=l :totals %></th>
63
- <th/>
64
- <th/>
65
- <th class="hours"><%='%d:%02d' % [day_total.to_i, 60 * (day_total % 1)] %></th>
66
- </tr>
67
- <% end %>
68
- </table>
69
- <%= submit_tag l(:save) %>
70
- <%= back_or_link_to l(:back), '' %>
71
- <% end %>
72
-
73
-
74
- <% if @period %>
75
- <%= link_to l(:back), :controller => 'periods', :action => :show, :id => @period %>
76
- <% end %>
77
- </div>
78
-
79
- <% if @period %>
80
- <%=render :partial => '/periods/burn_down_chart' %>
81
- <% end %>
82
-
83
- <script type="text/JavaScript">
84
- //<!--
85
- <% if last_work.completed_at %>
86
- start_field = $('work_work_account_name')
87
- <% else %>
88
- start_field = $('work_<%=last_work.id%>_completed_at_time')
89
- <% end %>
90
- start_field.focus();
91
- start_field.select();
92
- //-->
93
- </script>