knjtasks 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +18 -0
  4. data/Gemfile.lock +66 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/files/database_schema.rb +174 -0
  10. data/lib/knjtasks.rb +172 -0
  11. data/locales/da_DK/LC_MESSAGES/default.mo +0 -0
  12. data/locales/da_DK/LC_MESSAGES/default.po +1153 -0
  13. data/locales/da_DK/title.txt +1 -0
  14. data/locales/en_GB/title.txt +1 -0
  15. data/models/class_comment.rb +44 -0
  16. data/models/class_customer.rb +13 -0
  17. data/models/class_email_check.rb +7 -0
  18. data/models/class_project.rb +22 -0
  19. data/models/class_task.rb +163 -0
  20. data/models/class_task_assigned_user.rb +62 -0
  21. data/models/class_task_check.rb +26 -0
  22. data/models/class_timelog.rb +82 -0
  23. data/models/class_user.rb +125 -0
  24. data/models/class_user_project_link.rb +66 -0
  25. data/models/class_user_rank.rb +3 -0
  26. data/models/class_user_rank_link.rb +17 -0
  27. data/models/class_user_task_list_link.rb +17 -0
  28. data/pages/admin.rhtml +7 -0
  29. data/pages/comment_edit.rhtml +121 -0
  30. data/pages/comment_update_id_per_obj.rhtml +41 -0
  31. data/pages/customer_edit.rhtml +69 -0
  32. data/pages/customer_search.rhtml +80 -0
  33. data/pages/customer_show.rhtml +50 -0
  34. data/pages/frontpage.rhtml +198 -0
  35. data/pages/project_edit.rhtml +129 -0
  36. data/pages/project_search.rhtml +82 -0
  37. data/pages/project_show.rhtml +203 -0
  38. data/pages/task_check_edit.rhtml +98 -0
  39. data/pages/task_edit.rhtml +168 -0
  40. data/pages/task_search.rhtml +131 -0
  41. data/pages/task_show.rhtml +454 -0
  42. data/pages/timelog_edit.rhtml +134 -0
  43. data/pages/timelog_search.rhtml +318 -0
  44. data/pages/user_edit.rhtml +223 -0
  45. data/pages/user_login.rhtml +83 -0
  46. data/pages/user_profile.rhtml +89 -0
  47. data/pages/user_rank_search.rhtml +95 -0
  48. data/pages/user_search.rhtml +136 -0
  49. data/pages/user_show.rhtml +87 -0
  50. data/pages/workstatus.rhtml +320 -0
  51. data/scripts/fckeditor_validate_login.rb +23 -0
  52. data/spec/knjtasks_spec.rb +115 -0
  53. data/spec/spec_helper.rb +12 -0
  54. data/threads/thread_mail_task_comments.rb +114 -0
  55. data/www/api/task.rhtml +9 -0
  56. data/www/api/user.rhtml +20 -0
  57. data/www/clean.rhtml +14 -0
  58. data/www/css/default.css +186 -0
  59. data/www/gfx/body_bg.jpg +0 -0
  60. data/www/gfx/button_bg.png +0 -0
  61. data/www/gfx/main_box_design.png +0 -0
  62. data/www/gfx/main_box_left.png +0 -0
  63. data/www/gfx/main_box_right.png +0 -0
  64. data/www/gfx/main_box_top.png +0 -0
  65. data/www/gfx/main_box_top_left.png +0 -0
  66. data/www/gfx/main_box_top_right.png +0 -0
  67. data/www/index.rhtml +154 -0
  68. data/www/js/default.js +112 -0
  69. metadata +208 -0
@@ -0,0 +1,134 @@
1
+ <%
2
+ task_id = _get["task_id"] if _get["task_id"].to_i > 0
3
+
4
+ if _get["choice"] == "dosave"
5
+ save_hash = {
6
+ :time => _post["textime"],
7
+ :time_transport => _post["textimetransport"],
8
+ :transport_length => _post["textransportlength"],
9
+ :date => Datet.in(_post["texdate"]),
10
+ :comment => _post["texcomment"],
11
+ :task_id => _post["seltask"],
12
+ :invoiced => Knj::Web.checkval(_post["cheinvoiced"], 1, 0)
13
+ }
14
+ end
15
+
16
+ if _get["timelog_id"].to_i > 0
17
+ timelog = _ob.get(:Timelog, _get["timelog_id"])
18
+ task_id = timelog.task.id
19
+ date_val = Datet.in(timelog[:date]).out(:time => false)
20
+ time_val = timelog[:time]
21
+ time_transport_val = timelog[:time_transport]
22
+ url = "&timelog_id=#{timelog.id}"
23
+
24
+ if _get["choice"] == "dosave"
25
+ timelog.update(save_hash)
26
+ exit
27
+ end
28
+
29
+ if _get["choice"] == "dodelete"
30
+ _ob.delete(timelog)
31
+ exit
32
+ end
33
+ else
34
+ date_val = Datet.new.out(:time => false)
35
+ time_val = "00:00:00"
36
+ time_transport_val = "00:00:00"
37
+
38
+ if _get["choice"] == "dosave"
39
+ begin
40
+ timelog = _ob.add(:Timelog, save_hash)
41
+ rescue RuntimeError => e
42
+ puts e.message
43
+ end
44
+
45
+ exit
46
+ end
47
+ end
48
+ %>
49
+
50
+ <form method="get" onsubmit="return do_save_timelog();">
51
+
52
+ <%=_site.boxt(_("Enter details"))%>
53
+ <table class="form" id="formtimelogedit">
54
+ <%
55
+ opts = _ob.list_optshash(:Task, {:debug => false})
56
+ raise "Empty opts?" if opts.empty?
57
+
58
+ print _hb.inputs({
59
+ :title => _("Task"),
60
+ :name => :seltask,
61
+ :value => task_id,
62
+ :opts => opts,
63
+ :descr => _("On which task should this timelog be saved?")
64
+ },{
65
+ :title => _("Time"),
66
+ :name => :textime,
67
+ :value => time_val,
68
+ :descr => _("How much time should be logged?")
69
+ },{
70
+ :title => _("Time transportation"),
71
+ :name => :textimetransport,
72
+ :value => time_transport_val,
73
+ :descr => _("How much time was used on transportation?")
74
+ },{
75
+ :title => _("Transportation length"),
76
+ :name => :textransportlength,
77
+ :value => [timelog, :transport_length],
78
+ :descr => _("How many km was used on transportation?")
79
+ },{
80
+ :title => _("Date"),
81
+ :name => :texdate,
82
+ :value => date_val,
83
+ :descr => _("On which date was the time used?")
84
+ },{
85
+ :title => _("Invoiced"),
86
+ :name => :cheinvoiced,
87
+ :value => [timelog, :invoiced],
88
+ :descr => _("If this timelog has been invoiced or not.")
89
+ },{
90
+ :title => _("Comment"),
91
+ :name => :texcomment,
92
+ :value => [timelog, :comment],
93
+ :type => :textarea,
94
+ :descr => _("What whas done using the time."),
95
+ :height => 200
96
+ })
97
+ %>
98
+ <tr>
99
+ <td colspan="2" class="buttons">
100
+ <input type="submit" value="<%=_("Save")%>" />
101
+ </td>
102
+ </tr>
103
+ </table>
104
+ <%=_site.boxb%>
105
+
106
+ </form>
107
+
108
+ <script type="text/javascript">
109
+ modal_on_opened(function(){
110
+ $("#textime").focus();
111
+ });
112
+
113
+ function do_save_timelog(){
114
+ urlstr = "clean.rhtml?show=timelog_edit&choice=dosave<%=url%>";
115
+ formdata = forms_inputs_read($("#formtimelogedit"));
116
+
117
+ $.ajax({
118
+ type: "POST",
119
+ url: urlstr,
120
+ data: formdata,
121
+ complete: function(data){
122
+ if (data.responseText.length > 0){
123
+ alert(data.responseText);
124
+ }else{
125
+ modal_close();
126
+ events.call("on_timelog_added");
127
+ events.call("do_timelogs_update");
128
+ }
129
+ }
130
+ });
131
+
132
+ return false;
133
+ }
134
+ </script>
@@ -0,0 +1,318 @@
1
+ <%
2
+ _hb.alert(_("You do not have permission to view this page.")).back if !_site.has_rank?("admin")
3
+
4
+ if _get["choice"] == "dosearch"
5
+ begin
6
+ date_from = Datet.in(_get["texdatefrom"])
7
+ rescue
8
+ _hb.alert(_("Invalid date-from.")).back
9
+ end
10
+
11
+ begin
12
+ date_to = Datet.in(_get["texdateto"])
13
+ rescue
14
+ _hb.alert(_("Invalid date-to.")).back
15
+ end
16
+ else
17
+ date_from = Datet.new
18
+ date_from.day = 1
19
+
20
+ date_to = Datet.new
21
+ date_to.day = date_to.days_in_month
22
+ end
23
+
24
+ if _get["choice"] == "domarktimelogsasinvoiced"
25
+ _post["tlog_ids"].split(";").each do |tlog_id|
26
+ tlog = _ob.get(:Timelog, tlog_id)
27
+ tlog[:invoiced] = 1 if !tlog.invoiced?
28
+ end
29
+
30
+ exit
31
+ end
32
+
33
+ print _site.header(_("Timelogs"))
34
+ %>
35
+
36
+ <form method="get" onsubmit="return do_submit_criterias();">
37
+ <%=Knj::Web.hiddens([{:name => :show, :value => :timelog_search}, {:name => :choice, :value => :dosearch}, {:name => :users, :value => ""}, {:name => :projects, :value => ""}])%>
38
+
39
+ <%=_site.boxt(_("Enter criteria"), "400px")%>
40
+ <table class="form">
41
+ <%
42
+ print _hb.inputs({
43
+ :title => _("Date from"),
44
+ :name => :texdatefrom,
45
+ :value => date_from.out(:time => false),
46
+ :descr => _("If you only want timelogs from a specific date and up.")
47
+ },{
48
+ :title => _("Date to"),
49
+ :name => :texdateto,
50
+ :value => date_to.out(:time => false),
51
+ :descr => _("If you only want timelogs up to a specific date.")
52
+ },{
53
+ :title => _("Comment"),
54
+ :name => :texcomment,
55
+ :value => _get["texcomment"],
56
+ :descr => _("A part of the comment in the timelog you are looking for.")
57
+ },{
58
+ :title => _("Users"),
59
+ :name => :seluser,
60
+ :opts => _ob.list_optshash(:User, :list_args => {"orderby" => "name"}),
61
+ :multiple => true,
62
+ :size => 5,
63
+ :values => _get["users"].to_s.split(";").map{|ele| ele.to_i},
64
+ :descr => _("If you want to find timelogs from specific users.")
65
+ },{
66
+ :title => _("Projects"),
67
+ :name => :selproject,
68
+ :opts => _ob.list_optshash(:Project, :list_args => {"orderby" => "name"}),
69
+ :multiple => true,
70
+ :size => 5,
71
+ :values => _get["projects"].to_s.split(";").map{|ele| ele.to_i},
72
+ :descr => _("If you want to find timelogs from specific projects.")
73
+ },{
74
+ :title => _("Invoiced"),
75
+ :name => :selinvoiced,
76
+ :value => _get["selinvoiced"],
77
+ :descr => _("If you only want to view invoiced, uninvoiced or all timelogs."),
78
+ :opts => {
79
+ "" => _("All"),
80
+ "1" => _("Only invoiced"),
81
+ "0" => _("Only un-invoiced")
82
+ }
83
+ })
84
+ %>
85
+ <tr>
86
+ <td colspan="2" class="buttons">
87
+ <input type="submit" value="<%=_("Search")%>" />
88
+ </td>
89
+ </tr>
90
+ </table>
91
+ <%=_site.boxb%>
92
+
93
+ </form>
94
+
95
+ <script type="text/javascript">
96
+ $("#texdatefrom").focus();
97
+
98
+ function do_submit_criterias(){
99
+ $("input[name=users]").val(select_values({sel: $("#seluser"), selected: true, expl: ";"}));
100
+ $("input[name=projects]").val(select_values({sel: $("#selproject"), selected: true, expl: ";"}));
101
+ $("#seluser").val(false);
102
+ return true;
103
+ }
104
+
105
+ function do_mark_invoiced(){
106
+ tlog_ids = []
107
+ $("input[type=hidden]", $("#table_customer_message")).each(function(){
108
+ id = $(this).attr("name").substring(9);
109
+ tlog_ids.push(id);
110
+ });
111
+
112
+ $.ajax({
113
+ type: "POST",
114
+ url: "/clean.rhtml?show=timelog_search&choice=domarktimelogsasinvoiced",
115
+ data: {tlog_ids: tlog_ids.join(";")},
116
+ async: true,
117
+ cache: false,
118
+ complete: function(data){
119
+ if (data.responseText.length > 0){
120
+ alert(data.responseText);
121
+ }else{
122
+ alert("<%=_'All timelogs was marked as invoiced.'%>");
123
+ }
124
+ }
125
+ });
126
+ }
127
+ </script>
128
+
129
+ <%
130
+ if _get["choice"] == "dosearch"
131
+ args = {"orderby" => "date"}
132
+
133
+ if _get["texdatefrom"].to_s.length > 0
134
+ args["date_from"] = date_from
135
+ end
136
+
137
+ if _get["texdateto"].to_s.length > 0
138
+ args["date_to"] = date_to
139
+ end
140
+
141
+ if _get["texcomment"].to_s.length > 0
142
+ args["comment_search"] = _get["texcomment"]
143
+ end
144
+
145
+ if _get["users"].to_s.length > 0
146
+ args["user_id"] = _get["users"].to_s.split(";")
147
+ end
148
+
149
+ if _get["projects"].to_s.length > 0
150
+ args["project_id"] = _get["projects"].to_s.split(";")
151
+ end
152
+
153
+ if _get["selinvoiced"].to_s == "1" or _get["selinvoiced"].to_s == "0"
154
+ args["invoiced"] = _get["selinvoiced"].to_s
155
+ end
156
+
157
+ args_count = args.merge(:count => true)
158
+
159
+ tlogs = _ob.list(:Timelog, args)
160
+ tlogs_count = _ob.list(:Timelog, args_count)
161
+
162
+ %>
163
+ <br />
164
+
165
+ <%=_site.boxt(_("Sum"), "350px")%>
166
+ <table class="form">
167
+ <%
168
+ print _hb.inputs({
169
+ :title => _("Total hours"),
170
+ :type => :info,
171
+ :value => Knj::Locales.number_out(tlogs_count[:sum_time].to_f / 3600, 1) + " / " + Knj::Locales.number_out(tlogs_count[:sum_time_transport].to_f / 3600, 1),
172
+ :descr => _("The total amount of hours of all the found time-logs (first hours used then time used on transport).")
173
+ },{
174
+ :title => _("Total transport"),
175
+ :type => :info,
176
+ :value => Knj::Locales.number_out(tlogs_count[:sum_transport_length], 1),
177
+ :descr => _("Total km's of transport used in all the timelogs found.")
178
+ })
179
+ %>
180
+ </table>
181
+ <%=_site.boxb%>
182
+
183
+ <br />
184
+
185
+ <%=_site.boxt(_("Results"))%>
186
+ <table class="form">
187
+ <thead>
188
+ <tr>
189
+ <th><%=_"Timelog"%></th>
190
+ <th><%=_"User"%></th>
191
+ <th><%=_"Date"%></th>
192
+ <th><%=_"Task"%></th>
193
+ <th><%=_"Invoiced"%></th>
194
+ <th><%=_"Time"%> / <%=_"Transport"%></th>
195
+ <th><%=_"Transport length"%></th>
196
+ </tr>
197
+ </thead>
198
+ <tbody>
199
+ <%
200
+ tlogs_sorted = {}
201
+ tlogs.each do |tlog|
202
+ dbt = Knj::Db::Dbtime.new(tlog[:time])
203
+ dbt_transport = Knj::Db::Dbtime.new(tlog[:time_transport])
204
+ tlogs_sorted[tlog[:task_id]] = [] if !tlogs_sorted.has_key?(tlog[:task_id])
205
+ tlogs_sorted[tlog[:task_id]] << tlog
206
+
207
+ %>
208
+ <tr>
209
+ <td>
210
+ <%=tlog.html%>
211
+ </td>
212
+ <td>
213
+ <%=tlog.user_html%>
214
+ </td>
215
+ <td>
216
+ <%=tlog.date_str(:time => false)%>
217
+ </td>
218
+ <td>
219
+ <%=tlog.task_html%>
220
+ </td>
221
+ <td>
222
+ <%=Knj::Strings.yn_str(tlog.invoiced?, _("Yes"), _("No"))%>
223
+ </td>
224
+ <td>
225
+ <%=Knj::Locales.number_out(dbt.hours_total, 1)%> / <%=Knj::Locales.number_out(dbt_transport.hours_total, 1)%>
226
+ </td>
227
+ <td>
228
+ <%=Knj::Locales.number_out(tlog[:transport_length], 0)%>
229
+ </td>
230
+ </tr>
231
+ <%
232
+ end
233
+
234
+ if tlogs.empty?
235
+ %>
236
+ <tr>
237
+ <td colspan="1" class="error">
238
+ <%=_("No timelogs were found.")%>
239
+ </td>
240
+ </tr>
241
+ <%
242
+ end
243
+ %>
244
+ </tbody>
245
+ </table>
246
+ <%=_site.boxb%>
247
+
248
+ <br />
249
+
250
+ <%=_site.boxt(_("Customer message"))%>
251
+ <table class="list" id="table_customer_message">
252
+ <thead>
253
+ <tr>
254
+ <th><%=_"Date"%>/<%=_"Hours"%></th>
255
+ <th><%=_"User"%></th>
256
+ <th><%=_"Description"%></th>
257
+ </tr>
258
+ </thead>
259
+ <tbody>
260
+ <%
261
+ tlogs_sorted.each do |task_id, tlogs_arr|
262
+ task = _ob.get(:Task, task_id)
263
+
264
+ %>
265
+ <tr>
266
+ <td colspan="3" class="tdt" style="padding-top: 10px;">
267
+ <%=task.name.html%>
268
+ </td>
269
+ </tr>
270
+ <%
271
+
272
+ first = true
273
+ tlogs_arr.each do |tlog|
274
+ if !first
275
+ %>
276
+ <tr>
277
+ <td colspan="3"><hr size="1" color="#cfcfcf" /></td>
278
+ </tr>
279
+ <%
280
+ end
281
+
282
+ first = false if first
283
+
284
+ %>
285
+ <tr>
286
+ <td style="text-align: center;">
287
+ <input type="hidden" name="timelogs_<%=tlog.id%>" value="1" />
288
+
289
+ <%=tlog.date_str(:time => false)%><br />
290
+ <%=Knj::Locales.number_out(tlog.time_dbt.hours_total, 2)%> / <%=Knj::Locales.number_out(tlog.time_transport_dbt.hours_total, 2)%>
291
+ </td>
292
+ <td class="nowrap">
293
+ <%=tlog.user.name.html%>
294
+ </td>
295
+ <td>
296
+ <%=tlog.comment_html%>
297
+ </td>
298
+ </tr>
299
+ <%
300
+ end
301
+ end
302
+
303
+ if !tlogs_sorted.empty?
304
+ %>
305
+ <tr>
306
+ <td colspan="3" style="padding-top: 15px; text-align: right;">
307
+ <input type="button" value="<%=_"Mark timelogs as invoiced"%>" onclick="if (confirm('<%=_"Are you sure you want to mark all the found timelogs as invoiced?"%>')){do_mark_invoiced();}" />
308
+ </td>
309
+ </tr>
310
+ <%
311
+ end
312
+ %>
313
+ </tbody>
314
+ </table>
315
+ <%=_site.boxb%>
316
+ <%
317
+ end
318
+ %>