backlog 0.21.0 → 0.21.1

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.
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ == 0.21.1 2008-02-04
2
+
3
+ === Features
4
+
5
+ * Added link from weekly work sheet summary to details view with editing option.
6
+
7
+ === Fixes
8
+
9
+ * Changed to nag for work locks at 10am instead of every 24 hours after server startup.
10
+ * Added localizations for Lock/Unlock operations.
11
+ * Fixed bug when updating work records without tasks.
12
+ * Changed formatting of week total of work account to two decimals in the weekly work sheet.
13
+ * Fixed editing in weekly work sheet details view.
14
+
1
15
  == 0.21.0 2008-02-02
2
16
 
3
17
  === Features
data/Rakefile CHANGED
@@ -46,6 +46,8 @@ task :release_all do
46
46
  Rake::Task[:post_news].invoke
47
47
  end
48
48
 
49
+ # Remember to set timeout in /usr/lib/ruby/gems/1.8/gems/rubyforge-0.4.4/lib/http-access2.rb
50
+ # @send_timeout = 3600
49
51
  desc 'Release the application as a Java EE WAR file to RubyForge'
50
52
  task :release_war do
51
53
  FileUtils.rm_rf 'WEB-INF' if File.exists? 'WEB-INF'
@@ -73,13 +73,18 @@ class WorksController < ApplicationController
73
73
  @work.attributes = params[:work]
74
74
  @estimate = Estimate.new(params[:estimate])
75
75
  @work_accounts = WorkAccount.find(:all)
76
- @tasks = [@work.task] + Task.find_open
76
+ @tasks = Task.find_open
77
+ @tasks.unshift @work.task if @work.task
77
78
  @users = User.find(:all)
78
79
  end
79
80
 
80
81
  def update
81
82
  if update_work
82
- back_or_redirect_to :controller => 'periods', :action => 'show', :id => @work.task.period, :task_id => @work.task.id
83
+ if @work.task
84
+ back_or_redirect_to :controller => 'periods', :action => 'show', :id => @work.task.period, :task_id => @work.task.id
85
+ else
86
+ back_or_redirect_to :controller => 'welcome', :action => 'index'
87
+ end
83
88
  else
84
89
  @task = @work.task
85
90
  edit
@@ -199,7 +204,7 @@ class WorksController < ApplicationController
199
204
 
200
205
  render :partial => 'description_list'
201
206
  end
202
-
207
+
203
208
  def calculate_hours
204
209
  calculated_duration = (Time.parse(params[:completed_at]) - Time.parse(params[:started_at]))
205
210
  new_value = '%2d:%02d' % [calculated_duration / 3600, (calculated_duration % 3600) / 60]
@@ -19,9 +19,9 @@ class WorkLockNagger
19
19
  loop do
20
20
  puts "Nagging"
21
21
  begin
22
- p late_work_locks = WorkLock.find(
23
- :all,
24
- :conditions => ["end_on < ? and not exists (select id from work_locks wl2 where wl2.user_id = work_locks.user_id and wl2.end_on > work_locks.end_on)", Date.today ])
22
+ late_work_locks = WorkLock.find(
23
+ :all,
24
+ :conditions => ["end_on < ? and not exists (select id from work_locks wl2 where wl2.user_id = work_locks.user_id and wl2.end_on > work_locks.end_on)", Date.today ])
25
25
  late_users = late_work_locks.map{|wl| wl.user}.uniq
26
26
  late_users.each do |u|
27
27
  missing_date = (u.work_locks.last.end_on + 7)
@@ -29,11 +29,15 @@ class WorkLockNagger
29
29
  week = missing_date.cweek
30
30
  WorkLockNotify.deliver_nag(u, week, url + "/#{year}/#{week}")
31
31
  end
32
+ now = Time.now
33
+ next_nag_time = Time.local(now.year, now.month, now.hour < 10 ? now.day : now.day + 1, 10, 0, 0)
34
+ sleep_duration = next_nag_time - now
35
+ puts "Sleeping #{sleep_duration.to_i / 3600} hours #{(sleep_duration.to_i % 3600) / 60} minutes and #{sleep_duration.to_i % 60} seconds."
36
+ sleep sleep_duration
32
37
  rescue Exception => e
33
38
  p e
34
39
  end
35
40
  puts "Nag ends"
36
- sleep 24.hours
37
41
  end
38
42
  end
39
43
 
@@ -0,0 +1,20 @@
1
+ <div style="float: left"><%=link_to(image_tag('arrow_left.png'), :year => (@week > 1 ? @year : @year - 1), :week => (@week > 1 ? @week - 1 : 52))%></div>
2
+ <div style="float: right"><%=link_to(image_tag('arrow_right.png'), :year => (@week < 52 ? @year : @year + 1), :week => (@week < 52 ? @week + 1 : 1))%></div>
3
+
4
+ <div align="right">
5
+ <% lock_action = @lock ? :unlock : :lock %>
6
+ [<%=link_to l(lock_action), with_detour(:controller => 'work_locks', :action => lock_action, :year => @year, :week => @week) %>]
7
+ <%unless controller.action_name == 'weekly_work_sheet'%>
8
+ [<%=link_to l(:details), :action => :weekly_work_sheet, :year => @year, :week => @week %>]
9
+ <% end %>
10
+ <%unless controller.action_name == 'weekly_work_sheet_by_work_account'%>
11
+ [<%=link_to l(:totals), :action => :weekly_work_sheet_by_work_account, :year => @year, :week => @week %>]
12
+ <% end %>
13
+ <% if @lock %>
14
+ [<%=link_to l(:spreadsheet), :action => :timeliste, :year => @year, :week => @week %>]
15
+ <% else %>
16
+ [<%=detour_to l(:new_work), :controller => 'works', :action => :new %>]
17
+ <% end %>
18
+ </div>
19
+
20
+ <br clear="all" />
@@ -5,22 +5,9 @@
5
5
  <% invoicing = @rows.find {|r| r.find {|w| w && w.work_account.enable_invoicing?}} %>
6
6
  <% columns = 2 + (track_times ? 1 : 0) + (invoicing ? 1 : 0) %>
7
7
 
8
- <div style="float: left"><%=link_to(image_tag('arrow_left.png'), :year => (@week > 1 ? @year : @year - 1), :week => (@week > 1 ? @week - 1 : 52))%></div>
9
- <div style="float: right"><%=link_to(image_tag('arrow_right.png'), :year => (@week < 52 ? @year : @year + 1), :week => (@week < 52 ? @week + 1 : 1))%></div>
10
-
11
8
  <h1>Work for week <%=@week%><%=user? ? " for #{user.login}" : ''%></h1>
12
9
 
13
- <div align="right">
14
- <% lock_action = @lock ? :unlock : :lock %>
15
- [<%=link_to l(lock_action), :controller => 'work_locks', :action => lock_action %>]
16
- [<%=detour_to l(:new_work), :controller => 'works', :action => :new %>]
17
- [<%=link_to 'Timeliste', :action => :timeliste, :id => @week %>]
18
- [<%= if params[:with_empty]
19
- link_to 'Hide empty work records'
20
- else
21
- link_to 'Show empty work records', :with_empty => 'yes'
22
- end %>]
23
- </div>
10
+ <%=render :partial => 'weekly_work_sheet_buttons'%>
24
11
 
25
12
  <table border="1">
26
13
  <tr>
@@ -47,47 +34,69 @@ end %>]
47
34
  <% day_totals = Array.new(7, 0) %>
48
35
  <% for row in @rows %>
49
36
  <tr>
50
- <% row.each_with_index do |@work, day| %>
51
- <% if @work %>
52
- <% day_totals[day] += @work.hours %>
53
- <% week_total += @work.hours %>
54
- <td valign="top">
55
- <%=image_detour_to('hammer.png', l(:edit), {:controller => 'works', :action => :edit, :id => @work.id}, {:style => "float: left; border: 1px solid black"}) %>
56
- <!--
57
- <%=detour_to(h(@work.task.period.name), :controller => 'periods', :action => :show, :id => @work.task.period) if @work.task && @work.task.period %>
58
- -->
59
- <%=detour_to(h(@work.work_account.name), :controller => 'work_accounts', :action => :show, :id => @work.work_account_id) %>:
37
+ <% row.each_with_index do |@work, day| %>
38
+ <% if @work %>
39
+ <% day_totals[day] += @work.hours %>
40
+ <% week_total += @work.hours %>
41
+ <td valign="top">
42
+ <%=image_detour_to('hammer.png', l(:edit), {:controller => 'works', :action => :edit, :id => @work.id}, {:style => "float: left"}) %>
43
+ <% if @work.task_id %>
44
+ <%=detour_to(h(@work.task.description), :controller => 'tasks', :action => :edit, :id => @work.task_id)%>
45
+ <% else %>
46
+ <% field_id = "work_#{@work.id}_description" %>
47
+ <%=text_field(:work, :description, :id => field_id, :name => "work_#{@work.id}_description", :class => :task_description, :style => 'width: 8em', :disabled => @lock,
48
+ :onchange => "new Ajax.Updater('#{field_id}', '#{url_for(:action => :update, :id => @work.id)}' + '?work[description]=' + this.value);") %>
49
+ <% end %>
50
+ <br/>
60
51
  <!--
61
- <%=detour_to(h(@work.task.description), :controller => 'tasks', :action => :edit, :id => @work.task_id) if @work.task_id%>
52
+ <%=detour_to(h(@work.task.period.name), :controller => 'periods', :action => :show, :id => @work.task.period) if @work.task && @work.task.period %>
62
53
  -->
63
- </td>
64
- <% if invoicing %>
65
- <td id="invoice_<%=@work.id%>" valign="top">
66
- <%=check_box(:work, :invoice, :onchange => "new Ajax.Updater('invoice_#{@work}', '#{url_for(:action => :set_work_invoice, :id => @work)}' + '?value=' + this.checked);", :disabled => @lock) if @work.work_account.enable_invoicing? %>
67
- </td>
68
- <% end %>
69
- <% if track_times %>
70
- <td align="left" valign="top"><%=text_field(:work, :started_at_time, :class => :task_time, :disabled => @lock) %> -
71
- <%=text_field(:work, :completed_at_time, :class => :task_time, :disabled => @lock) %></td>
54
+ <%=detour_to(h(@work.work_account.name), :controller => 'work_accounts', :action => :show, :id => @work.work_account_id) %>
55
+ </td>
56
+ <% if invoicing %>
57
+ <td id="invoice_<%=@work.id%>" valign="top">
58
+ <% form_id = "work_#{@work.id}_invoice_form" %>
59
+ <% field_id = "work_#{@work.id}_invoice" %>
60
+ <%=check_box(:work, :invoice, :id => field_id, :name => field_id, :onchange => "new Ajax.Updater('invoice_#{@work}', '#{url_for(:action => :set_work_invoice, :id => @work)}' + '?value=' + this.checked);", :disabled => @lock) if @work.work_account.enable_invoicing? %>
61
+ </td>
62
+ <% end %>
63
+ <% if track_times %>
64
+ <td align="left" valign="top">
65
+ <% form_id = "work_#{@work.id}_time_form" %>
66
+ <% field_id = "work_#{@work.id}_started_at_time" %>
67
+ <form id="<%=form_id%>">
68
+ <%=text_field(:work, :started_at_time, :class => :task_time, :disabled => @lock,
69
+ :onchange => "new Ajax.Updater('#{field_id}', '#{url_for(:action => :update, :id => @work.id)}' + '?work[started_at_time]=' + this.value);") %> -
70
+ <%=text_field(:work, :completed_at_time, :class => :task_time, :disabled => @lock,
71
+ :onchange => "new Ajax.Updater('work_#{@work.id}_completed_at_time', '#{url_for(:action => :update, :id => @work.id)}' + '?work[completed_at_time]=' + this.value);") %>
72
+ </form>
73
+ </td>
74
+ <% end %>
75
+ <td align="right" valign="top">
76
+ <% form_id = "work_#{@work.id}_hours_form" %>
77
+ <% field_id = "work_#{@work.id}_hours_time" %>
78
+ <form id="<%=form_id%>">
79
+ <%=text_field(:work, :hours_time, :value => '%d:%02d' % [@work.hours , 60 * @work.hours % 60], :class => 'task_hours', :disabled => @lock,
80
+ :onchange => "new Ajax.Updater('#{field_id}', '#{url_for(:action => :update, :id => @work.id)}' + '?work[hours_time]=' + this.value);") %>
81
+ </form>
82
+ </td>
83
+ <% else %>
84
+ <td/>
85
+ <% if invoicing %>
86
+ <td/>
87
+ <% end %>
88
+ <% if track_times %>
89
+ <td/>
90
+ <% end %>
91
+ <td/>
72
92
  <% end %>
73
- <td align="right" valign="top"><%=text_field(:work, :hours, :value => '%.2f' % @work.hours, :class => 'task_hours') %></td>
74
- <% else %>
75
- <td/>
76
- <% if invoicing %>
77
- <td/>
78
- <% end %>
79
- <% if track_times %>
80
- <td/>
81
- <% end %>
82
- <td/>
83
93
  <% end %>
84
- <% end %>
85
94
  </tr>
86
95
  <% end %>
87
96
  <tr>
88
- <% (0..6).each do |day| %>
89
- <th class="hours" colspan="<%=columns%>"><%='%.2f' % day_totals[day] if day_totals[day] > 0%></th>
90
- <% end %>
97
+ <% (0..6).each do |day| %>
98
+ <th class="hours" colspan="<%=columns%>"><%='%.2f' % day_totals[day] if day_totals[day] > 0%></th>
99
+ <% end %>
91
100
  <th class="hours"><%= '%.2f' % week_total %></th>
92
101
  </tr>
93
102
  </table>
@@ -3,20 +3,7 @@
3
3
  <div id="spotlight">
4
4
  <% columns = 2 %>
5
5
 
6
- <div style="float: left"><%=link_to(image_tag('arrow_left.png'), :year => (@week > 1 ? @year : @year - 1), :week => (@week > 1 ? @week - 1 : 52))%></div>
7
- <div style="float: right"><%=link_to(image_tag('arrow_right.png'), :year => (@week < 52 ? @year : @year + 1), :week => (@week < 52 ? @week + 1 : 1))%></div>
8
-
9
- <div align="right">
10
- <% lock_action = @lock ? :unlock : :lock %>
11
- [<%=link_to l(lock_action), with_detour(:controller => 'work_locks', :action => lock_action, :year => @year, :week => @week) %>]
12
- <% if @lock %>
13
- [<%=link_to l(:spreadsheet), :action => :timeliste, :year => @year, :week => @week %>]
14
- <% else %>
15
- [<%=detour_to l(:new_work), :controller => 'works', :action => :new %>]
16
- <% end %>
17
- </div>
18
-
19
- <br clear="all" />
6
+ <%=render :partial => 'weekly_work_sheet_buttons'%>
20
7
 
21
8
  <table border="1">
22
9
  <tr>
@@ -38,20 +25,21 @@
38
25
  <% if total %>
39
26
  <% day_totals[day] += total %>
40
27
  <% week_totals[work_account] += total %>
41
- <td align="right" valign="top"><%='%.2f' % total%></td>
28
+ <td align="right" valign="top"><%='%d:%02d' % [total, 60 * total % 60]%></td>
42
29
  <% else %>
43
30
  <td/>
44
31
  <% end %>
45
32
  <% end %>
46
- <td align="right"><%=week_totals[work_account]%></td>
33
+ <td align="right"><%='%d:%02d' % [week_totals[work_account], 60 * week_totals[work_account] % 60]%></td>
47
34
  </tr>
48
35
  <% end %>
49
36
  <tr>
50
37
  <th><%=l :totals%></th>
51
38
  <% (0..6).each do |day| %>
52
- <th class="hours"><%='%.2f' % day_totals[day] if day_totals[day] > 0%></th>
39
+ <th class="hours"><%='%d:%02d' % [day_totals[day], 60 * day_totals[day] % 60] if day_totals[day] > 0%></th>
53
40
  <% end %>
54
- <th class="hours"><%= '%.2f' % week_totals.values.inject(0) {|total, work_account_total| total + work_account_total} %></th>
41
+ <% week_total = week_totals.values.inject(0) {|total, work_account_total| total + work_account_total} %>
42
+ <th class="hours"><%= '%d:%02d' % [week_total, 60 * week_total % 60] %></th>
55
43
  </tr>
56
44
  </table>
57
45
  </div>
data/lang/en.yaml CHANGED
@@ -21,6 +21,7 @@ customer: Customer
21
21
  daily_work_sheet: Daily work sheet
22
22
  delete: Delete
23
23
  description: Description
24
+ details: Details
24
25
  done: Done
25
26
  down: Down
26
27
  edit: Edit
@@ -46,6 +47,7 @@ invoice_code: Invoice Code
46
47
  invoice_short: Inv.
47
48
  left: Left
48
49
  listing_works: Recorded work
50
+ lock: Lock
49
51
  log_in: Log in
50
52
  log_out: Log out
51
53
  main_backlog: Main Backlog
@@ -88,6 +90,7 @@ select: Select
88
90
  shortcuts: Shortcuts
89
91
  signup: Sign Up
90
92
  specify: Specify
93
+ spreadsheet: Spreadsheet
91
94
  start: Start
92
95
  start_on: Start on
93
96
  start_work: Start
@@ -104,6 +107,7 @@ track_todo: Estimates
104
107
  track_done: Track work done
105
108
  track_times: Track start and stop times
106
109
  tuesday: Tuesday
110
+ unlock: Unlock
107
111
  unplanned_tasks: Unplanned tasks
108
112
  up: Up
109
113
  user: User
data/lang/no.yaml CHANGED
@@ -21,6 +21,7 @@ customer: Kunde
21
21
  daily_work_sheet: Timeføringsskjema
22
22
  delete: Slett
23
23
  description: Beskrivelse
24
+ details: Detaljer
24
25
  done: Utført
25
26
  down: Ned
26
27
  edit: Rediger
@@ -46,6 +47,7 @@ invoice_code: Faktureringskode
46
47
  invoice_short: Fakt
47
48
  left: Venstre
48
49
  listing_works: Registrert arbeid
50
+ lock: Lås
49
51
  log_in: Log inn
50
52
  log_out: Log ut
51
53
  main_backlog: Hovedliste
@@ -88,6 +90,7 @@ select: Velg
88
90
  shortcuts: Knapper
89
91
  signup: Innmelding
90
92
  specify: Spesifisèr
93
+ spreadsheet: Regneark
91
94
  start: Start
92
95
  start_on: Start på
93
96
  start_work: Start arbeid
@@ -103,6 +106,7 @@ track_todo: Estimater
103
106
  track_done: Spor utført arbeid
104
107
  track_times: Spor start- og stopptider
105
108
  tuesday: Tirsdag
109
+ unlock: Lås opp
106
110
  unplanned_tasks: Ikke planlagte oppgaver
107
111
  up: Opp
108
112
  user: Bruker
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.21.0
4
+ version: 0.21.1
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-02 00:00:00 +01:00
12
+ date: 2008-02-05 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -156,6 +156,7 @@ files:
156
156
  - app/views/works/_row_field.rhtml
157
157
  - app/views/works/_form.rhtml
158
158
  - app/views/works/weekly_work_sheet.rhtml
159
+ - app/views/works/_weekly_work_sheet_buttons.rhtml
159
160
  - app/views/works/show.rhtml
160
161
  - app/views/works/weekly_work_sheet_by_work_account.rhtml
161
162
  - app/views/layouts