Improve stempel status layout
[infodrom.org/service.infodrom.org] / src / InfoCon / stempel / status.wml
1 #include <infocon.style>
2 #include "common.inc"
3
4 <future>
5 <page func=InfoCon title="Stempeluhr">
6 <script type="text/javascript" src="<root_prefix>jquery.editable.js"></script>
7
8 <?
9   session_name('STEMPEL');
10   session_start();
11
12   $stati = false;
13   function display_tables()
14   {
15     global $month;
16     global $cust;
17     global $status;
18     global $dbh;
19     global $stati;
20     $wdays = array('So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa');
21
22     $name = load_customers();
23
24     $table_head = '<h3 class="bar">Kunde: %s</h3><script type="text/javascript">plant(%d,%.2f);</script>
25   <form action="status.php" method="POST">
26   <table class="smallfont border" id="table_%d" width="100%%" cellpadding=0 cellspacing=0>
27   <thead>
28   <tr class="head">
29     <th width=15%% colspan="2">Datum</th>
30     <th width=5%%>Dauer</th>
31     <th width=5%%>St.</th>
32     <th width=75%% align=left>Arbeitsbeschreibung</th>
33   </tr>
34   </thead>
35   <tbody>';
36
37     if (!is_array($stati))
38       $stati = find_status();
39
40     $table_foot = '</table><div align="center"><p>';
41
42     foreach ($stati as $k=>$v)
43       $table_foot .= sprintf('<input type="radio" name="status" value="%s"%s>%s&nbsp;', $k, 0==$k?' checked':'', $v);
44     $table_foot .= '<input type="submit" class="button" value="Aktualisieren" onclick="return status_change(event)"></p></div>'.
45                   '<input type="hidden" name="fields" value="%d">'.
46                   '</form>';
47
48     $table_row = '<tr class="t%d" status="%d"><td>%s</td><td>%s</td><td align="center" onclick="toggle_checkbox(%d,this)">%s</td>' .
49       '<td align="center" onclick="toggle_checkbox(%d,this)">%s</td><td><span class="edit" route="Stempel/EditTask" item_id="%d">%s</span></td></tr>';
50     $table_sum = '</tbody><tfoot><tr class="t%d" onclick="edit_task_finish(this)">' .
51         '<td colspan="2">&nbsp;</td><td align="center">%s</td><td>&nbsp;</td><td>Summe</td></tr></tfoot>';
52
53     $query = "SELECT stempel.oid,stempel.id,stempel.status,start,customer,time,task,kurz FROM stempel JOIN stempel_status ON (stempel.status = stempel_status.id) WHERE time IS NOT NULL ";
54     if (isset($month) && strlen($month))
55       $query .= "AND cast(start AS TEXT) LIKE '".$month."-%' ";
56     if (isset($cust) && strlen($cust))
57       $query .= "AND customer ='".$cust."' ";
58
59     if (isset($status) && strlen($status)) {
60       if ($status != 'all')
61         $query .= "AND status = $status ";
62     } else
63       $query .= "AND status = 0 ";
64     $query .= "ORDER BY customer,start";
65
66     $sth = pg_exec ($dbh, $query);
67
68     $form = 0;
69     $customer = '';
70     while ($row = pg_fetch_array ($sth)) {
71
72       if ($customer != $row['customer']) {
73         if (strlen($customer)) {
74           printf($table_sum, $color, min2hour($sum));
75           printf($table_foot, $fieldnr);
76           $form++;
77         }
78         $cname = $name[$row['customer']]['name'];
79         if (!strlen($cname)) $cname = ucfirst($row['customer']);
80         printf($table_head, $cname, $form, $name[$row['customer']]['rate'], $form);
81         $customer = $row['customer'];
82         $fieldnr = 0;
83         $sum = 0;
84         $color = 0;
85       }
86
87       $sum += $row['time'];
88       $d = explode(' ', $row['start']);
89
90       $check = sprintf('<input type="checkbox" class="checkbox" name="id_%d" value="%d" onclick="add_sum(%d,this)">',
91                        $fieldnr++,
92                        $row['id'],
93                        $form);
94       $dt = new Datetime($d[0]);
95       $date = sprintf('<span onclick="toggle_checkbox(%d,this)">%s, %s</span>', $form, $wdays[$dt->format('w')], $d[0]);
96       printf($table_row, $color, $row['status'], $check, $date, $form, min2hour($row['time']), $form, $row['kurz'],
97              $row['id'],
98              htmlspecialchars($row['task'], ENT_COMPAT | ENT_HTML401, 'ISO-8859-1'));
99       $color = !$color;
100     }
101     if (pg_num_rows($sth) > 0) {
102       printf($table_sum, $color, min2hour($sum));
103       printf($table_foot, $fieldnr);
104     }
105   }
106
107   function find_customers()
108   {
109     global $dbh;
110
111     $a = array();
112     $query = "SELECT DISTINCT customer FROM stempel ORDER BY customer";
113     $sth = pg_exec ($dbh, $query);
114
115     while ($row = pg_fetch_array ($sth))
116       $a[] = $row[0];
117
118     return $a;
119   }
120
121   $dbh = pg_pconnect ("<dbhost>", "<dbport>", "<dbname>")
122          or die("Unable to connect to SQL server");
123
124   pg_exec ($dbh, "SET DateStyle = 'ISO'") or die("Datenbank-Abfrage!");
125
126   if (isset($_POST["status"]) && isset($_POST["fields"])) {
127     $msg = update_db();
128     $_SESSION['redirect'] = true;
129     header('Location: status.php');
130     exit;
131   } elseif ($_SESSION['redirect']) {
132     $month = $_SESSION['save']["month"];
133     $cust = $_SESSION['save']["customer"];
134     $status = $_SESSION['save']["status"];
135     $_SESSION['redirect'] = false;
136   } else {
137     if (isset($_GET['month'])) {
138       $month = $_GET['month'];
139       $_SESSION['save']['month'] = $month;
140       unset($_SESSION['save']['customer']);
141       unset($_SESSION['save']['status']);
142     } else
143       if (isset($_POST["filter"])) {
144         $month = $_POST["month"];
145         $cust = $_POST["customer"];
146         $status = $_POST["status"];
147         $_SESSION['save']['month'] = $month;
148         $_SESSION['save']['customer'] = $cust;
149         $_SESSION['save']['status'] = $status;
150       } else {
151         $month = date('Y-m');
152         $_SESSION['save']['month'] = $month;
153         unset($_SESSION['save']['customer']);
154         unset($_SESSION['save']['status']);
155       }
156   }
157 ?>
158
159 <script src="<root_prefix>basics.js"></script>
160 <script type="text/javascript">
161 <protect>
162 var color_checked = '#c4ffc3';
163 function format_int(value, width)
164 {
165   var s = value.toString();
166
167   while (s.length < width)
168     s = '0' + s;
169
170   return s;
171 }
172
173 function timestr(duration)
174 {
175     return format_int(Math.floor(duration / 60), 1) + ':'
176         + format_int(duration - (Math.floor(duration / 60) * 60), 2);
177 }
178
179 function strtime(time)
180 {
181     var a = time.split(':');
182     return parseInt(a[0],10) * 60 + parseInt(a[1],10);
183 }
184
185 function check(id, value)
186 {
187     var hours = $('#time_'+id);
188     var rate = $('#rate_'+id);
189     var sum = $('#sum_'+id);
190     var newval = 0;
191
192     $('table#table_'+id+' tbody tr:visible').each(function(i,e){
193         var checkbox = $(this).find('input[type="checkbox"]');
194         if (checkbox.prop('checked') != value) {
195             checkbox.prop('checked', !checkbox.prop('checked'));
196             if (checkbox.prop('checked'))
197                 $(this).css('background-color', color_checked);
198             else
199                 $(this).css('background-color', '');
200             add_sum(id, checkbox);
201         }
202     });
203
204     return false;
205 }
206
207 function plant(form, rate)
208 {
209   document.write('<div class="jscode">');
210   document.write('<input class="filter" id="filter_'+form+'" size="10" value="">');
211   document.write('<img class="filter" id="img_'+form+'" src="/pix/Actions-edit-delete-icon.png" border="0" ' +
212                  'title="Filter löschen">');
213   document.write('<input type="hidden" id="rate_'+form+'" value="'+rate+'">');
214   document.write('<a href="#" onclick="return check('+form+',true)">Check all</a>');
215   document.write("&nbsp;/&nbsp;");
216   document.write('<a href="#" onclick="return check('+form+',false)">Uncheck all</a>');
217   document.write("&nbsp;");
218   document.write('<span id="time_'+form+'" class="sum">0:00</span>' );
219   document.write('<span id="sum_'+form+'" class="sum">&euro;0.00</span>');
220   document.write("&nbsp;");
221   document.write('</div>');
222 }
223
224 function add_sum(form, checkbox)
225 {
226     var hours = $('#time_'+form);
227     var rate = $('#rate_'+form);
228     var sum = $('#sum_'+form);
229     var time = strtime($(checkbox).parents('tr:first').find('td:nth-child(3)').text());
230     var newval;
231
232     if ($(checkbox).prop('checked')) {
233         newval = strtime(hours.text()) + time;
234         $(checkbox).parents('tr:first').css('background-color', color_checked);
235     } else {
236         newval = strtime(hours.text()) - time;
237         $(checkbox).parents('tr:first').css('background-color', '');
238     }
239     hours.text(timestr(newval));
240     sum.html('&euro;' + ((newval/60)*rate.val()).toFixed(2));
241 }
242
243 var task_parent = null;
244 var task_title = '';
245 var task_id = 0;
246 function edit_task(obj)
247 {
248     if (task_id) {
249         if (task_id != obj.parentNode.children[0].children[0].value)
250             edit_task_save();
251     }
252
253     if (!task_id) {
254         task_parent = obj;
255         task_title = obj.innerHTML;
256         task_id = obj.parentNode.children[0].children[0].value;
257
258         var input = $('<input>');
259         input.val(obj.innerHTML.replace('&gt;', '>').replace('&lt;', '<').replace('&amp;', '&'));
260         input.css('fontSize', '100%').css('width', '100%').css('background', 'yellow');
261         obj.innerHTML = '';
262         $(obj).append(input);
263         input.focus();
264     }
265 }
266
267 function edit_task_save()
268 {
269     if (!task_parent) return;
270
271     if (task_parent.children[0].value != task_title)
272         $.invoke('Stempel/Task', {id: task_id, content: task_parent.children[0].value});
273
274     task_parent.innerHTML = task_parent.children[0].value;
275     task_parent = null;
276     task_title = '';
277     task_id = 0;
278 }
279
280 function edit_task_finish(obj)
281 {
282     if (task_id)
283         edit_task_save();
284 }
285
286 function toggle_checkbox(form, obj)
287 {
288     var row = $(obj).parents('tr:first');
289     var checkbox = row.find('input[type="checkbox"]')
290     checkbox.prop('checked', !checkbox.prop('checked'));
291
292     checkbox.checked = !checkbox.checked;
293     add_sum(form, checkbox);
294 }
295
296 function filter_change(e)
297 {
298     var form = $(this).attr('id').split('_')[1];
299     var filter = $('input#filter_'+form).val().toLowerCase();
300
301     var cnum = 0;
302     $('table#table_'+form+' tbody tr').not('.deleted').each(function(i,e){
303         if (filter.length) {
304             var td = $(this).find('td:nth-child(4)');
305             if (td.text().toLowerCase().indexOf(filter) > -1) {
306                 $(this).removeClass('t0').removeClass('t1').addClass('t'+cnum).show();
307                 cnum = cnum ? 0 : 1;
308             } else {
309                 if ($(this).find('input[type="checkbox"]').prop('checked')) {
310                     toggle_checkbox(form, td);
311                 }
312                 $(this).hide();
313             }
314         } else {
315             $(this).removeClass('t0').removeClass('t1').addClass('t'+cnum).show();
316             cnum = cnum ? 0 : 1;
317         }
318     });
319 }
320
321 function filter_clear(e)
322 {
323     var form = $(this).attr('id').split('_')[1];
324     $('div.jscode input.filter#filter_'+form).val('').keyup();
325 }
326
327 function status_change(e)
328 {
329     var ids = [];
330     var form = $(e.target).parents('form:first');
331     var p = $(e.target).parents('p:first');
332     form.find('tr').not('.deleted').find('input.checkbox').each(function(i,e){
333         if ($(this).prop('checked') == true)
334             ids.push($(this).val());
335     });
336
337     var new_status = 0;
338     p.find('input[name="status"]').each(function(i,e){
339         if ($(this).prop('checked') == true)
340             new_status = $(this).val();
341     });
342
343     $.invoke('Stempel/SetStatus', {status: new_status, ids: ids}, function(data){
344         for (var i=0; i < ids.length; i++) {
345             show_message('Positionen aktualisiert');
346             var checkbox = form.find('input.checkbox[value="'+ids[i]+'"]');
347             var row = checkbox.parents('tr:first');
348
349             checkbox.prop('checked',false);
350             add_sum(form.find('table:first').attr('id').split('_')[1], checkbox);
351
352             if (row.attr('status') != new_status)
353                 row.addClass('deleted').hide();
354         }
355     });
356
357     return false;
358 }
359
360 $(function(){
361     $('div.jscode input.filter').keyup(filter_change);
362     $('div.jscode img.filter').click(filter_clear);
363     make_editable('table.smallfont tr span.edit');
364 });
365 </protect>
366 </script>
367
368 <style type="text/css">
369 div.jscode {
370   text-align: right;
371   margin-top: -13px;
372   font-size: 12px;
373 }
374 div.jscode input.filter {
375   font-size: 90%;
376   position: relative;
377   bottom: 2px;
378 }
379 div.jscode img.filter {
380   position: relative;
381   bottom: -3px;
382   margin-left: 1px;
383   margin-right: 10px;
384 }
385 span.sum {
386   display: inline;
387   border: 1px solid #9b9b9b;
388   background: #d9e2ea;
389   width: 20px;
390   margin-left: 3px;
391 }
392 </style>
393
394 <?
395   if (!empty($msg))
396     echo $msg;
397   else {
398     display_tables();
399 ?>
400
401 <h3 class=bar>Display</h3>
402
403 <form action=status.php method=POST>
404 <select name=month>
405 <?
406   if (!is_array($months))
407     $months = find_months();
408
409   printf('<option value=""%s>alle</option>', !strlen($month)?' selected':'');
410   foreach ($months as $m) {
411     printf('<option value="%s"%s>%s</option>', $m, $month==$m?' selected':'', $m);
412   }
413 ?>
414 </select>
415
416 <select name=customer>
417 <?
418   if (!is_array($customers))
419     $customers = find_customers();
420
421   printf('<option value=""%s>alle</option>', !strlen($cust)?' selected':'');
422   foreach ($customers as $c) {
423     printf('<option value="%s"%s>%s</option>', $c, $cust==$c?' selected':'', $c);
424   }
425 ?>
426 </select>
427
428 <?
429   if (!is_array($stati))
430     $stati = find_status();
431
432   printf('<input type="radio" name="status" value="all"%s>alle&nbsp;', $status=='all'?' checked':'');
433   foreach ($stati as $k=>$v)
434     printf('<input type="radio" name="status" value="%s"%s>%s&nbsp;', $k, $status==$k?' checked':'', $v);
435 ?>
436
437 <input type="hidden" name="filter" value="form">
438 <input class="button" type="submit" value="Display">
439 </form>
440
441 <? } ?>
442 </page>
443
444 # Local variables:
445 # mode: php
446 # end: