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.
- data/History.txt +17 -4
- data/app/controllers/absences_controller.rb +64 -0
- data/app/controllers/periods_controller.rb +1 -1
- data/app/controllers/tasks_controller.rb +6 -4
- data/app/controllers/user_controller.rb +7 -0
- data/app/controllers/works_controller.rb +21 -16
- data/app/helpers/absences_helper.rb +2 -0
- data/app/models/absence.rb +14 -0
- data/app/models/task.rb +3 -2
- data/app/models/work.rb +33 -21
- data/app/views/absences/_form.rhtml +10 -0
- data/app/views/absences/edit.rhtml +9 -0
- data/app/views/absences/list.rhtml +27 -0
- data/app/views/absences/new.rhtml +8 -0
- data/app/views/absences/show.rhtml +8 -0
- data/app/views/layouts/absences.rhtml +17 -0
- data/app/views/tasks/_task.rhtml +1 -1
- data/app/views/tasks/edit.rhtml +1 -1
- data/app/views/user/edit.rhtml +36 -1
- data/app/views/works/_row.rhtml +19 -5
- data/app/views/works/_row_field.rhtml +14 -3
- data/app/views/works/daily_work_sheet.rhtml +81 -12
- data/app/views/works/list_excel.rhtml +1 -1
- data/app/views/works/timeliste.rhtml +3 -3
- data/app/views/works/update_row.rjs +3 -1
- data/app/views/works/update_time.rjs +2 -2
- data/app/views/works/weekly_work_sheet.rhtml +3 -3
- data/db/migrate/028_create_absences.rb +34 -0
- data/db/schema.rb +11 -2
- data/lang/en.yaml +4 -0
- data/lang/no.yaml +4 -0
- data/lib/change_column_null_migration_fix.rb +2 -0
- data/test/fixtures/absences.yml +11 -0
- data/test/fixtures/works.yml +10 -5
- data/test/functional/absences_controller_test.rb +93 -0
- data/test/functional/tasks_controller_test.rb +3 -2
- data/test/functional/works_controller_test.rb +33 -6
- data/test/test_helper.rb +3 -2
- data/test/unit/absence_test.rb +31 -0
- data/test/unit/work_test.rb +7 -0
- data/vendor/plugins/rails_time/MIT-LICENSE +20 -0
- data/vendor/plugins/rails_time/README +28 -0
- data/vendor/plugins/rails_time/init.rb +2 -0
- data/vendor/plugins/rails_time/lib/activerecord_time_extension.rb +28 -0
- data/vendor/plugins/rails_time/lib/time_of_day.rb +81 -0
- data/vendor/plugins/rails_time/test/database.yml +18 -0
- data/vendor/plugins/rails_time/test/rails_time_test.rb +122 -0
- data/vendor/plugins/rails_time/test/schema.rb +10 -0
- data/vendor/plugins/rails_time/test/test_helper.rb +17 -0
- metadata +28 -3
- data/app/views/works/daily_work_sheet_old.rhtml +0 -93
@@ -0,0 +1,17 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
+
<title>Absences: <%= controller.action_name %></title>
|
8
|
+
<%= stylesheet_link_tag 'scaffold' %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
|
12
|
+
<p style="color: green"><%= flash[:notice] %></p>
|
13
|
+
|
14
|
+
<%= yield %>
|
15
|
+
|
16
|
+
</body>
|
17
|
+
</html>
|
data/app/views/tasks/_task.rhtml
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
<% if @task.work_started? -%>
|
32
32
|
<% remote_form_for(:work, :url => {:controller => 'works', :action => 'update_time', :id => @task.started_work}) do |f| %>
|
33
33
|
<%=submit_tag('checkmark', :value => l(:save), :style => 'display: none')%>
|
34
|
-
<%=f.text_field '
|
34
|
+
<%=f.text_field 'start_time', :id => "work_#{@task.started_work.id}_start_time", :tabindex => i+1, :value => @task.started_work.start_time.strftime('%H:%M'),
|
35
35
|
:class => :task_time, :maxlength => 5 %>
|
36
36
|
<% end %>
|
37
37
|
<% elsif @task.track_times? && (@task.period_id.nil? || @task.period.active?) %>
|
data/app/views/tasks/edit.rhtml
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
<% if @task.work_started? -%>
|
32
32
|
<% remote_form_for(:work, :url => {:controller => 'works', :action => 'update_time', :id => @task.started_work}) do |f| %>
|
33
33
|
<%=submit_tag('checkmark', :value => l(:save), :style => 'display: none')%>
|
34
|
-
<%=l :started_at%> <%=f.text_field '
|
34
|
+
<%=l :started_at%> <%=f.text_field 'start_time', :id => "work_#{@task.started_work.id}_start_time", :value => @task.started_work.started_at.strftime('%H:%M'),
|
35
35
|
:class => :task_time, :maxlength => 5 %>
|
36
36
|
<% end %>
|
37
37
|
<% elsif @task.track_times? && (@task.period_id.nil? || @task.period.active?) %>
|
data/app/views/user/edit.rhtml
CHANGED
@@ -52,7 +52,7 @@
|
|
52
52
|
|
53
53
|
<div id="lfeature">
|
54
54
|
<div class="btitle">
|
55
|
-
<h4><%=l :
|
55
|
+
<h4><%=l :work_lock_subscriptions %></h4>
|
56
56
|
</div>
|
57
57
|
|
58
58
|
<% if @user == current_user %>
|
@@ -79,3 +79,38 @@
|
|
79
79
|
<%=image_link_to_remote "email#{'_grey' unless monitoring}.png", "#{l(monitoring ? :stop : :start)} #{l(:monitoring)}", {:action => :toggle_work_lock_monitoring, :id => @user.id}, {:id => "work_lock_monitor_icon_#{current_user.id}", :style => 'float: right'} %>
|
80
80
|
<% end %>
|
81
81
|
</div>
|
82
|
+
|
83
|
+
<div id="lfeature">
|
84
|
+
<div class="btitle">
|
85
|
+
<h4><%=l :holidays_used %></h4>
|
86
|
+
</div>
|
87
|
+
|
88
|
+
<table align="right">
|
89
|
+
<tr>
|
90
|
+
<th>Date</th>
|
91
|
+
</tr>
|
92
|
+
<% for date in @holidays %>
|
93
|
+
<tr>
|
94
|
+
<td align="center"><%=date%></td>
|
95
|
+
</tr>
|
96
|
+
<% end %>
|
97
|
+
</table>
|
98
|
+
</div>
|
99
|
+
|
100
|
+
<div id="lfeature">
|
101
|
+
<div class="btitle">
|
102
|
+
<h4><%=l :sick_days_used %></h4>
|
103
|
+
</div>
|
104
|
+
|
105
|
+
<table align="right">
|
106
|
+
<tr>
|
107
|
+
<th>Date</th>
|
108
|
+
</tr>
|
109
|
+
<% for date in @sick_days %>
|
110
|
+
<tr>
|
111
|
+
<td align="center"><%=date%></td>
|
112
|
+
</tr>
|
113
|
+
<% end %>
|
114
|
+
</table>
|
115
|
+
</div>
|
116
|
+
|
data/app/views/works/_row.rhtml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<tr id="work_<%=@work.id%>" style="border: 1px solid black">
|
2
2
|
<td>
|
3
3
|
<% remote_form_for :work, :url => {:action => :update_row, :id => @work.id, :next_field => :customer_name}, :html => {:id => "work_#{@work.id}_form"} do |f|%>
|
4
|
-
<%=f.select :work_account_id, @work_accounts.map {|wa| [wa.name, wa.id]}, {}, :onchange => "
|
4
|
+
<%=f.select :work_account_id, @work_accounts.map {|wa| [wa.name, wa.id]}, {}, :onchange => "form.submit()"%>
|
5
5
|
<% end %>
|
6
6
|
</td>
|
7
7
|
<td>
|
@@ -10,17 +10,31 @@
|
|
10
10
|
<% end %>
|
11
11
|
</td>
|
12
12
|
<td>
|
13
|
-
<%=render :partial => 'row_field', :locals => {:field => 'description',
|
13
|
+
<%=render :partial => 'row_field', :locals => {:field => 'description',
|
14
|
+
:next_field => 'start_time', :next_row_id => next_row_id, :previous_row_id => previous_row_id} %>
|
14
15
|
</span>
|
15
16
|
<td align="right">
|
16
|
-
<%=render :partial => 'row_field', :locals => {:field => '
|
17
|
+
<%=render :partial => 'row_field', :locals => {:field => 'start_time',
|
18
|
+
:next_field => 'completed_at_time', :next_row_id => next_row_id, :previous_row_id => previous_row_id} %>
|
17
19
|
</td>
|
18
20
|
<td align="left">
|
19
|
-
<%=render :partial => 'row_field', :locals => {:field => 'completed_at_time',
|
21
|
+
<%=render :partial => 'row_field', :locals => {:field => 'completed_at_time',
|
22
|
+
:next_field => 'hours_time', :next_row_id => next_row_id, :previous_row_id => previous_row_id} %>
|
20
23
|
</td>
|
21
24
|
<td align="right">
|
22
25
|
<% remote_form_for :work, :url => {:action => :update_row, :id => @work.id, :next_field => :invoice} do |f|%>
|
23
|
-
<%=f.text_field :hours_time, :value => (@work.hours && @work.hours > 0 ? t(@work.hours) : ''), :id => "work_#{@work.id}_hours_time", :class => 'task_hours',
|
26
|
+
<%=f.text_field :hours_time, :value => (@work.hours && @work.hours > 0 ? t(@work.hours) : ''), :id => "work_#{@work.id}_hours_time", :class => 'task_hours',
|
27
|
+
:onkeypress => "
|
28
|
+
if(event.keyCode == 40) {
|
29
|
+
e = $('work#{"_#{next_row_id}" if next_row_id}_hours_time');
|
30
|
+
e.focus();
|
31
|
+
e.select();
|
32
|
+
} else if(event.keyCode == 38) {
|
33
|
+
e = $('work#{"_#{previous_row_id}" if previous_row_id}_hours_time');
|
34
|
+
e.focus();
|
35
|
+
e.select();
|
36
|
+
}",
|
37
|
+
:onchange => "new Ajax.Request('/works/update_row/#{@work.id}?next_field=invoice', {asynchronous:true, evalScripts:true, parameters:Form.serialize(form)})"%>
|
24
38
|
<% end %>
|
25
39
|
</td>
|
26
40
|
<td style="text-align: left">
|
@@ -1,6 +1,17 @@
|
|
1
|
-
<% remote_form_for :work, :url => {:action => :update_row, :id => @work.id, :next_field => next_field} do |f|%>
|
1
|
+
<% remote_form_for :work, :url => {:action => :update_row, :id => @work.id, :field=>field, :next_field => next_field} do |f|%>
|
2
2
|
<%=text_field :work, field, :id => "work_#{@work.id}_#{field}",
|
3
|
-
:class => ('task_time' if field=~/
|
4
|
-
|
3
|
+
:class => ('task_time' if field=~/_time$/),
|
4
|
+
:onchange => "new Ajax.Request('/works/update_row/#{@work.id}?field=#{field}&next_field=#{next_field}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(form)});",
|
5
|
+
:onkeypress => "
|
6
|
+
if(event.keyCode == 40) {
|
7
|
+
e = $('work#{"_#{next_row_id}" if next_row_id}_#{field}');
|
8
|
+
e.focus();
|
9
|
+
e.select();
|
10
|
+
} else if(event.keyCode == 38) {
|
11
|
+
e = $('work#{"_#{previous_row_id}" if previous_row_id}_#{field}');
|
12
|
+
e.focus();
|
13
|
+
e.select();
|
14
|
+
}",
|
15
|
+
:value => (field=~/_time$/ ? @work.send(field) && @work.send(field).strftime('%H:%M') : @work.send(field) )
|
5
16
|
%>
|
6
17
|
<% end %>
|
@@ -4,18 +4,26 @@
|
|
4
4
|
|
5
5
|
<div style="float: left"><%=image_link_to('arrow_left.png', l(:previous_week), {:id => @date - 7}, :class => nil)%></div>
|
6
6
|
<div style="float: left"><%=image_link_to('arrow_left.png', l(:previous_day), {:id => @date-1}, :class => nil)%></div>
|
7
|
+
<%=link_to l(:weekly_work_sheet), :action => :weekly_work_sheet_by_work_account%>
|
7
8
|
<div style="float: right"><%=image_link_to('arrow_right.png', l(:next_week), {:id => @date + 7}, :class => nil)%></div>
|
8
9
|
<div style="float: right"><%=image_link_to('arrow_right.png', l(:next_day), {:id => @date+1}, :class => nil)%></div>
|
9
10
|
|
10
11
|
<br clear="all" />
|
11
12
|
|
13
|
+
<div id="absence">
|
14
|
+
<% form_for :absence, :html => {:id => :absence_form}, :url => with_detour({:controller => 'absences', :action => :create}) do |f| %>
|
15
|
+
<%=f.hidden_field :on, :value => @date %>
|
16
|
+
<%=f.radio_button :reason, '', :disabled => !@works.empty?, :onchange => 'form.submit()' %><label for="absence_reason_">Work day</label>
|
17
|
+
<%=f.radio_button :reason, 'HOLIDAY', :disabled => !@works.empty?, :onchange => 'form.submit()' %><label for="absence_reason_holiday">Holiday</label>
|
18
|
+
<%=f.radio_button :reason, 'SICK', :disabled => !@works.empty?, :onchange => 'form.submit()' %><label for="absence_reason_sick">Sick day</label>
|
19
|
+
<% end %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<br clear="all" />
|
23
|
+
|
12
24
|
<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
25
|
|
26
|
+
<% if @absence.nil? || @works.size > 0 %>
|
19
27
|
<tr>
|
20
28
|
<th><%=l :account %></th>
|
21
29
|
<th><%=l :customer %></th>
|
@@ -26,13 +34,17 @@
|
|
26
34
|
<th><%=l :invoice %></th>
|
27
35
|
<th/>
|
28
36
|
</tr>
|
37
|
+
<% end %>
|
29
38
|
|
30
39
|
<% day_total = 0 %>
|
31
|
-
<%
|
40
|
+
<% @works.each_with_index do |@work, i| %>
|
32
41
|
<% day_total += @work.hours if @work %>
|
33
|
-
<%=render :partial => 'row'
|
42
|
+
<%=render :partial => 'row', :locals => {:next_row_id => @works[i+1] && @works[i+1].id,
|
43
|
+
:previous_row_id => @works[i-1] && @works[i-1].id} %>
|
34
44
|
<% end %>
|
35
45
|
<% last_work = @work %>
|
46
|
+
|
47
|
+
<% unless @absence %>
|
36
48
|
<% @work = nil %>
|
37
49
|
|
38
50
|
<% form_tag with_detour(:controller => 'works', :action => 'create') do %>
|
@@ -47,19 +59,74 @@
|
|
47
59
|
<%=text_field_with_auto_complete :work, :customer_name, {:value => '', :size => 16, :class => :task_description} %>
|
48
60
|
</td>
|
49
61
|
<td valign="bottom">
|
50
|
-
<%=text_field_with_auto_complete :work, :description,
|
62
|
+
<%=text_field_with_auto_complete :work, :description, :class => :task_description,
|
63
|
+
:onkeypress => "
|
64
|
+
if(event.keyCode == 38) {
|
65
|
+
e = $('work#{"_#{last_work.id}" if last_work}_description');
|
66
|
+
e.focus();
|
67
|
+
e.select();
|
68
|
+
} else if(event.keyCode == 13) {
|
69
|
+
e = $('work_work_account_name');
|
70
|
+
if(e.value == '') {
|
71
|
+
e.focus();
|
72
|
+
e.select();
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
}"
|
76
|
+
%>
|
51
77
|
</td>
|
52
78
|
<td align="right" valign="bottom">
|
53
|
-
<%=text_field :work, :
|
79
|
+
<%=text_field :work, :start_time, :value => last_work && last_work.completed_at && last_work.completed_at.strftime('%H:%M'), :class => 'task_time',
|
80
|
+
:onkeypress => "
|
81
|
+
if(event.keyCode == 38) {
|
82
|
+
e = $('work#{"_#{last_work.id}" if last_work}_start_time');
|
83
|
+
e.focus();
|
84
|
+
e.select();
|
85
|
+
} else if(event.keyCode == 13) {
|
86
|
+
e = $('work_work_account_name');
|
87
|
+
if(e.value == '') {
|
88
|
+
e.focus();
|
89
|
+
e.select();
|
90
|
+
return false;
|
91
|
+
}
|
92
|
+
}"
|
93
|
+
%>
|
54
94
|
</td>
|
55
95
|
<td align="left" valign="bottom">
|
56
|
-
<%=text_field :work, :completed_at_time, :class => 'task_time',
|
96
|
+
<%=text_field :work, :completed_at_time, :class => 'task_time',
|
97
|
+
:onkeypress => "
|
98
|
+
if(event.keyCode == 38) {
|
99
|
+
e = $('work#{"_#{last_work.id}" if last_work}_completed_at_time');
|
100
|
+
e.focus();
|
101
|
+
e.select();
|
102
|
+
} else if(event.keyCode == 13) {
|
103
|
+
e = $('work_work_account_name');
|
104
|
+
if(e.value == '') {
|
105
|
+
e.focus();
|
106
|
+
e.select();
|
107
|
+
return false;
|
108
|
+
}
|
109
|
+
}",
|
57
110
|
:value => @work && @work.completed_at.strftime('%H:%M'),
|
58
111
|
:onchange => "update_hours(this.form);"
|
59
112
|
%>
|
60
113
|
</td>
|
61
114
|
<td align="right" valign="bottom">
|
62
|
-
<%=text_field :work, :hours_time, :value => '', :class => 'task_hours'
|
115
|
+
<%=text_field :work, :hours_time, :value => '', :class => 'task_hours',
|
116
|
+
:onkeypress => "
|
117
|
+
if(event.keyCode == 38) {
|
118
|
+
e = $('work#{"_#{last_work.id}" if last_work}_hours_time');
|
119
|
+
e.focus();
|
120
|
+
e.select();
|
121
|
+
} else if(event.keyCode == 13) {
|
122
|
+
e = $('work_work_account_name');
|
123
|
+
if(e.value == '') {
|
124
|
+
e.focus();
|
125
|
+
e.select();
|
126
|
+
return false;
|
127
|
+
}
|
128
|
+
}"
|
129
|
+
%>
|
63
130
|
</td>
|
64
131
|
<td align="left" valign="bottom">
|
65
132
|
<%=check_box :work, :invoice %>
|
@@ -67,6 +134,8 @@
|
|
67
134
|
<td valign="bottom">
|
68
135
|
</td>
|
69
136
|
</tr>
|
137
|
+
<% end %>
|
138
|
+
|
70
139
|
<tr>
|
71
140
|
<td/>
|
72
141
|
<th><%=l :totals %></th>
|
@@ -101,7 +170,7 @@ function update_hours(form, id) {
|
|
101
170
|
id_str = '_' + id;
|
102
171
|
}
|
103
172
|
|
104
|
-
var started_at = $('work' + id_str + '
|
173
|
+
var started_at = $('work' + id_str + '_start_time');
|
105
174
|
var completed_at = $('work' + id_str + '_completed_at_time');
|
106
175
|
var hours_field = $('work' + id_str + '_hours_time');
|
107
176
|
|
@@ -69,7 +69,7 @@
|
|
69
69
|
<Row>
|
70
70
|
<Cell><Data ss:Type="String"><%=[work.task && work.task.description, work.description].compact.join(' ') %></Data></Cell>
|
71
71
|
<Cell><Data ss:Type="String"><%=work.user && work.user.name %></Data></Cell>
|
72
|
-
<Cell><Data ss:Type="Date"><%=work.
|
72
|
+
<Cell><Data ss:Type="Date"><%=work.started_on.strftime('%Y-%m-%d') %><%=work.start_time && work.start_time.strftime(' %H:%M:%S') %></Data></Cell>
|
73
73
|
<Cell><Data ss:Type="Date"><%=work.completed_at && work.completed_at.strftime('%Y-%m-%d %H:%M:%S') %></Data></Cell>
|
74
74
|
<Cell><Data ss:Type="Number"><%=work.hours %> %></Data></Cell>
|
75
75
|
</Row>
|
@@ -454,8 +454,8 @@
|
|
454
454
|
<% invoice_works_per_day = @work_totals_per_work_account[work_account_id][0]%>
|
455
455
|
<% if invoice_works_per_day.find{|total| total > 0} %>
|
456
456
|
<Row>
|
457
|
-
<Cell ss:StyleID="s24"><Data ss:Type="
|
458
|
-
<Cell ss:StyleID="s25"
|
457
|
+
<Cell ss:StyleID="s24"><Data ss:Type="String"><%=WorkAccount.find(work_account_id).invoice_code %></Data></Cell>
|
458
|
+
<Cell ss:StyleID="s25"><Data ss:Type="String"><%=WorkAccount.find(work_account_id).name %></Data></Cell>
|
459
459
|
<Cell ss:StyleID="s25"><Data ss:Type="String"> X</Data></Cell>
|
460
460
|
<Cell ss:StyleID="s25"/>
|
461
461
|
<Cell ss:StyleID="s25"/>
|
@@ -472,7 +472,7 @@
|
|
472
472
|
<% internal_works_per_day = @work_totals_per_work_account[work_account_id][1]%>
|
473
473
|
<% if internal_works_per_day.find{|total| total > 0} %>
|
474
474
|
<Row>
|
475
|
-
<Cell ss:StyleID="s24"><Data ss:Type="String"><%=work_account_id%></Data></Cell>
|
475
|
+
<Cell ss:StyleID="s24"><Data ss:Type="String"><%=WorkAccount.find(work_account_id).invoice_code%></Data></Cell>
|
476
476
|
<Cell ss:StyleID="s25"><Data ss:Type="String"><%=WorkAccount.find(work_account_id).name %></Data></Cell>
|
477
477
|
<Cell ss:StyleID="s25"/>
|
478
478
|
<Cell ss:StyleID="s25"/>
|
@@ -1,7 +1,9 @@
|
|
1
1
|
page.replace "work_#{@work.id}", :partial => 'row', :object => @work
|
2
2
|
page.replace "notice", :partial => '/layouts/notice'
|
3
3
|
page.visual_effect(:highlight, "notice")
|
4
|
-
|
4
|
+
if @day_total
|
5
|
+
page.replace_html "hours_total", "#{'%d:%02d' % [@day_total.to_i, 60 * (@day_total % 1)]}"
|
6
|
+
end
|
5
7
|
page["work_#{@work.id}_#{@next_field}"].select
|
6
8
|
page["work_#{@work.id}_#{@next_field}"].focus
|
7
9
|
|
@@ -1,3 +1,3 @@
|
|
1
1
|
display_notice(page)
|
2
|
-
page["work_#{@work.id}
|
3
|
-
page.visual_effect(:highlight, "work_#{@work.id}
|
2
|
+
page["work_#{@work.id}_start_time"].value = @work.start_time && @work.start_time.strftime('%H:%M')
|
3
|
+
page.visual_effect(:highlight, "work_#{@work.id}_start_time")
|
@@ -63,10 +63,10 @@
|
|
63
63
|
<% if track_times %>
|
64
64
|
<td align="left" valign="top">
|
65
65
|
<% form_id = "work_#{@work.id}_time_form" %>
|
66
|
-
<% field_id = "work_#{@work.id}
|
66
|
+
<% field_id = "work_#{@work.id}_start_time" %>
|
67
67
|
<form id="<%=form_id%>">
|
68
|
-
<%=text_field(:work, :
|
69
|
-
:onchange => "new Ajax.Updater('#{field_id}', '#{url_for(:action => :update, :id => @work.id)}' + '?work[
|
68
|
+
<%=text_field(:work, :start_time, :class => :task_time, :disabled => @lock,
|
69
|
+
:onchange => "new Ajax.Updater('#{field_id}', '#{url_for(:action => :update, :id => @work.id)}' + '?work[start_time]=' + this.value);") %> -
|
70
70
|
<%=text_field(:work, :completed_at_time, :class => :task_time, :disabled => @lock,
|
71
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
72
|
</form>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class CreateAbsences < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :absences do |t|
|
4
|
+
t.column :user_id, :integer, :null => false, :references => [:users, :party_id]
|
5
|
+
t.column :on, :date, :null => false
|
6
|
+
t.column :reason, :string, :null => false
|
7
|
+
end
|
8
|
+
|
9
|
+
add_column :works, :started_on, :date, :null => true
|
10
|
+
add_column :works, :start_time, :time, :null => true
|
11
|
+
Work.find(:all).each do |w|
|
12
|
+
w.started_on = (w.started_at || w.completed_at).to_date
|
13
|
+
w.start_time = w.started_at && w.started_at.time_of_day
|
14
|
+
w.save!
|
15
|
+
end
|
16
|
+
change_column_null :works, :started_on, :date, false
|
17
|
+
remove_column :works, :started_at
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.down
|
21
|
+
add_column :works, :started_at, :timestamp
|
22
|
+
Work.find(:all).each do |w|
|
23
|
+
w.started_at = w.start_time && w.start_time.on(w.started_on)
|
24
|
+
w.save!
|
25
|
+
end
|
26
|
+
remove_column :works, :started_on
|
27
|
+
remove_column :works, :start_time
|
28
|
+
drop_table :absences
|
29
|
+
end
|
30
|
+
|
31
|
+
class Work < ActiveRecord::Base
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/db/schema.rb
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
# migrations feature of ActiveRecord to incrementally modify your database, and
|
3
3
|
# then regenerate this schema definition.
|
4
4
|
|
5
|
-
ActiveRecord::Schema.define(:version =>
|
5
|
+
ActiveRecord::Schema.define(:version => 28) do
|
6
|
+
|
7
|
+
create_table "absences", :force => true do |t|
|
8
|
+
t.column "user_id", :integer, :null => false
|
9
|
+
t.column "on", :date, :null => false
|
10
|
+
t.column "reason", :string, :null => false
|
11
|
+
end
|
6
12
|
|
7
13
|
create_table "backlogs", :force => true do |t|
|
8
14
|
t.column "name", :string, :limit => 64, :null => false
|
@@ -127,16 +133,19 @@ ActiveRecord::Schema.define(:version => 27) do
|
|
127
133
|
t.column "task_id", :integer
|
128
134
|
t.column "hours", :decimal, :precision => 6, :scale => 2, :default => 0.0, :null => false
|
129
135
|
t.column "completed_at", :datetime
|
130
|
-
t.column "started_at", :datetime
|
131
136
|
t.column "user_id", :integer
|
132
137
|
t.column "invoice", :boolean
|
133
138
|
t.column "work_account_id", :integer
|
134
139
|
t.column "customer_id", :integer
|
135
140
|
t.column "description", :string
|
141
|
+
t.column "started_on", :date, :null => false
|
142
|
+
t.column "start_time", :time
|
136
143
|
end
|
137
144
|
|
138
145
|
add_index "works", ["task_id", "completed_at"], :name => "index_works_on_task_id_and_completed_at"
|
139
146
|
|
147
|
+
add_foreign_key "absences", ["user_id"], "users", ["party_id"], :name => "absences_user_id_fkey"
|
148
|
+
|
140
149
|
add_foreign_key "backlogs", ["customer_id"], "customers", ["id"], :name => "backlogs_customer_id_fkey"
|
141
150
|
add_foreign_key "backlogs", ["work_account_id"], "work_accounts", ["id"], :name => "backlogs_work_account_id_fkey"
|
142
151
|
|