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