Documentation is available at workday.class.php
1 <?php
2 /**
3 *
4 * @version $Id: workday.class.php,v 1.6 2003/09/24 16:21:48 cybot_tm Exp $
5 * @category phpTimeSheet
6 * @package phpTimeSheet
7 */
8
9 /**
10 * reflects a day for a worker, and handles access to DB-Table WORKER_TIME
11 *
12 * @uses Date
13 * @uses Time
14 * @uses Worktype
15 * @uses Daytype
16 */
17 class WorkerDay
18 {
19
20 /**
21 * @var object Date date of day
22 * @since 1.4
23 */
24 var $date;
25
26 /**
27 * @var int worker_id
28 * @since 1.4
29 */
30 var $worker_id;
31
32 /**
33 * @var array of object Project
34 * @since 1.4
35 */
36 var $projects;
37
38 /**
39 * @var object Time start of worktime
40 * @since 1.4
41 */
42 var $come;
43
44 /**
45 * @var object Time end of worktime
46 * @since 1.4
47 */
48 var $go;
49
50 /**
51 * @var object Time amount of workspace
52 * @since 1.4
53 */
54 var $workspace;
55
56 /**
57 * @var object Time amount of overtime
58 * @since 1.4
59 */
60 var $over_time;
61
62 /**
63 * @var object Time amount o contracted hours
64 * @since 1.4
65 */
66 var $contracted_hours;
67
68 /**
69 * @var object Daytype
70 * @since 1.4
71 */
72 var $daytype;
73
74 /**
75 * @var object Worktype
76 * @since 1.4
77 */
78 var $worktype;
79
80 /**
81 *
82 * @uses SetDate()
83 * @uses SetWorkerId()
84 * @uses Date
85 * @param object Date
86 * @param int worker_id
87 * @return bool success
88 */
89 function WorkerDay($date, $worker_id)
90 {
91 $this->SetDate($date);
92 $this->SetWorkerId($worker_id);
93
94 return TRUE;
95 }
96
97 /**
98 * @uses $date
99 * @return object Date
100 */
101 function GetDate() { return $this->date; }
102
103 function GetWorkerId() { return $this->worker_id; }
104
105 /**
106 * Sets cuurent date
107 * @param mixed date object date or string
108 * @uses Date
109 */
110 function SetDate($date = null)
111 {
112 if ( null === $date )
113 {
114 $date = time();
115 }
116 $this->date = new Date($date);
117
118 return true;
119 }
120
121 /**
122 * Sets worker_id
123 *
124 * @uses $worker_id
125 */
126 function SetWorkerId($worker_id)
127 {
128 $this->worker_id = (int) $worker_id;
129 return true;
130 }
131
132 /**
133 * @uses PTS_TBL_WORKTYPE
134 * @uses PTS_TBL_DAYTYPE
135 * @uses PTS_TBL_WORKTIME
136 * @uses __FILE__
137 * @uses mysql_query()
138 */
139 function LoadWorkerTimes()
140 {
141 // first: load all times for this worker and all times for all workers past contract_start and before contract_end
142 $sql = '
143 SELECT `day`,
144 `allowed`,
145 SUBSTRING_INDEX(`contracted_hours`, ":", 2) AS `contracted_hours`,
146 SUBSTRING_INDEX(`go`, ":", 2) AS `go`,
147 SUBSTRING_INDEX(`come`, ":", 2) AS `come`,
148 SUBSTRING_INDEX(`workspace`, ":", 2) AS `workspace`,
149 SUBSTRING_INDEX(SEC_TO_TIME(TIME_TO_SEC(`go`) - TIME_TO_SEC(`come`)), ":", 2) AS `attend_time`,
150 SUBSTRING_INDEX(SEC_TO_TIME(TIME_TO_SEC(`go`) - TIME_TO_SEC(`come`) - TIME_TO_SEC(`workspace`)), ":", 2) AS `work_time`,
151 SUBSTRING_INDEX(SEC_TO_TIME(TIME_TO_SEC(`go`) - TIME_TO_SEC(`come`) - TIME_TO_SEC(`workspace`) - TIME_TO_SEC(`contracted_hours`)), ":", 2) AS `overtime`,
152 `' . PTS_TBL_WORKTYPE . '`.*,
153 `' . PTS_TBL_DAYTYPE . '`.*
154 FROM `' . PTS_TBL_WORKTIME . '`
155 LEFT JOIN `' . PTS_TBL_WORKTYPE . '`
156 ON `' . PTS_TBL_WORKTIME . '`.`worktype` = `' . PTS_TBL_WORKTYPE . '`.`id`
157 LEFT JOIN `' . PTS_TBL_DAYTYPE . '`
158 ON `' . PTS_TBL_WORKTIME . '`.`daytype` = `' . PTS_TBL_DAYTYPE . '`.`id`
159 WHERE `day` = "' . $this->date->Get() . '"
160 AND ( `worker` = ' . $this->GetId() . '
161 OR ( `worker` = 0
162 AND `day` BETWEEN "' . $this->GetContractStart() . '" AND "' . $this->GetContractEnd() . '" -- public times only in contract time
163 )
164 )';
165
166 $result = mysql_query($sql) or die('<pre>' . __FILE__ . ': ' . __LINE__ . "\n" . __CLASS__ . '::' . __FUNCTION__ . "\n" . $sql . "\n" . mysql_error());
167
168 while ( $row = mysql_fetch_assoc($result) )
169 {
170 if ( $row['day'] == date('Y-m-d') && $row['go'] == '00:00' )
171 {
172 // current row is today and worker is at work, so we have to add some missing information
173 $row['go'] = date('H:i');
174 $row['workspace'] = '00:' . $this->GetWorkspaceForDay($row['day']);
175 $row['contracted_hours'] = $this->GetContractedHoursForDay($row['day']);
176 $row['attend_time'] = time_sub($row['go'], $row['come']);
177 $row['work_time'] = time_sub($row['attend_time'], $row['workspace']);
178 $row['overtime'] = time_sub($row['work_time'], $row['contracted_hours']);
179 }
180
181 // adds time-information to days-array
182 $days[$row['day']] = $row;
183 }
184 }
185
186 function LoadProjectTimes()
187 {
188 $sql = '
189 SELECT `' . PTS_TBL_PROJECT_TIME . '`.*,
190 `' . PTS_TBL_PROJECT . '`.*,
191 CONCAT_WS(\'-\',`parent`.`pname`,`pids`.`pname`) AS `pname`
192 FROM `' . PTS_TBL_PROJECT_TIME . '`
193 LEFT JOIN `' . PTS_TBL_PROJECT . '`
194 ON `' . PTS_TBL_PROJECT_TIME . '`.`subpid` = `' . PTS_TBL_PROJECT . '`.`pindex`
195 LEFT JOIN `' . PTS_TBL_PROJECT . '` AS `parent`
196 ON `' . PTS_TBL_PROJECT . '`.`pparent` = `parent`.`pindex`
197 WHERE `' . PTS_TBL_PROJECT_TIME . '`.`day` = "' . $this->daydate . '"
198 AND `' . PTS_TBL_PROJECT_TIME . '`.`worker` = ' . $wid;
199
200 $result = mysql_query("$sql")or die(" <pre>WorkDay->load(): BadSelect:\n$sql\n".mysql_error());
201
202 $this->numentries = 0;
203 $this->totalhours = 0; // PATCH LUCKE : compute total hours in a day
204 while($row = mysql_fetch_array($result))
205 {
206 $pidid = $row["subpid"];
207 $this->pidnames[$pidid] = $row["pname"];
208 $this->hours[$pidid] = $row["hours"];
209 $this->numentries++;
210 $this->totalhours += $row["hours"]; // PATCH LUCKE : compute total hours in a day
211 }/*while($row = mysql_fetch_array($result)) */
212
213 $this->set_daytype($wid); //Urlaub-,Krankheits-oder Feiertag?
214 if ($this->daytype[0] != 0 && date("w", strtotime($this->daydate))!= 0){ //Stunden des Tages abhängig von Tagart aus DB holen
215 $hq = " SELECTtypeid, Mo, Di, Mi, Do, FrFROMsollzeit, workersWHEREworkers.windex=$widANDworkers.workertype = sollzeit.typeid";
216
217 $sollstd = mysql_fetch_row(mysql_query($hq)) or die("Fehler: ".mysql_error());
218 $hplus = $sollstd[date("w", strtotime($this->daydate))];
219
220 if (in_array(5,$this->daytype) xor in_array(6,$this->daytype)){ //halbe Tage
221 $hplus = $hplus/2;
222 }
223
224 $this->totalhours += $hplus;
225 }
226
227 //So, hier noch Arbeitsbeginn und -Ende holen
228 $sql = sprintf("SELECT * FROM times WHERE day = '%s' AND worker = %d", $this->daydate, $wid);
229 $result = mysql_query("$sql")or die (" WorkDayload(): BadSelect: $sql".mysql_error());
230
231 if ($row = mysql_fetch_array($result)){
232 $this->worktime["Kommt"] = $row["come"];
233 if ( $row['go'] == '00:00:00' ) {
234 $this->worktime["Geht"]= "__:__";
235 if ( $row['day'] == date('Y-m-d') )
236 $min = ( time() - strtotime($row['come']) ) / 60;
237 else
238 $min = 0;
239 }
240 else{
241 $this->worktime["Geht"] = $row["go"];
242 $min = (strtotime($row['go'])-strtotime($row['come']))/60;
243 }
244 $this->worktime["Min"] = $min;
245 $this->worktime["Anz"] = min_to_hours($min);
246 }
247 else{
248 $this->worktime["Kommt"] = "__:__";
249 $this->worktime["Geht"] = "__:__";
250 $this->worktime["Min"] = 0;
251 $this->worktime["Anz"] = min_to_hours($min);
252 }
253 }
254
255 /**
256 *
257 * @return bool success
258 */
259 function UpdateWorkType($worktype)
260 {
261 $sql = '
262 UPDATE `' . PTS_TBL_WORKTIME . '`
263 SET `worktype` = ' . $worktype . '
264 WHERE `day` = "' . $this->date->Get() . '"
265 AND `worker` = ' . $this->GetWorkerId();
266 echo $sql;
267 $result = mysql_query($sql) or die('<pre>' . __FILE__ . ': ' . __LINE__ . "\n" . __CLASS__ . '::' . __FUNCTION__ . "\n" . $sql . "\n" . mysql_error());
268
269 return true;
270 }
271
272 function get_next_day() { return date('Y-m-d',strtotime($this->daydate) + 24*60*60); }
273 function get_last_day() { return date('Y-m-d',strtotime($this->daydate) - 24*60*60); }
274
275 function is_pid_in_array($needle, $haystack){
276 return in_array($needle,array_flip($haystack));
277 }
278
279 function update__hours_from_form($post_vars){
280 $i=0;
281 if ( is_array($_REQUEST['pid']) ) {
282 while ( list($pindex, $phours) = each($_REQUEST['pid']) ) {
283 $phours = str_replace(",",".",$phours);
284 $phours = str_replace(":",".",$phours);
285 $this->replacehours[$pindex] = $phours;
286 }
287 }
288
289 // wenn einem neuen projekt stunden zugewiesen werden sollen
290 $_REQUEST['new_pid_hours'] = str_replace(",",".",$_REQUEST['new_pid_hours']);
291 $_REQUEST['new_pid_hours'] = str_replace(":",".",$_REQUEST['new_pid_hours']);
292
293 if ($_REQUEST['new_pid'] != '' && $_REQUEST['new_subpid'] != '' && $_REQUEST['new_pid_hours'] > 0) {
294
295 // falss es die teilleistung noch nicht gibt dann müssen wir sie erst anlegen
296 if ( intval($_REQUEST['new_subpid']) == 0 ) {
297 $sql = '
298 INSERT INTO `pids`
299 SET `pname` = "' . $_REQUEST['new_subpid'] . '",
300 `pstatus` = 1,
301 `ptyp` = "C",
302 `windex` = ' . get_workerid_by_name($_REQUEST['worker_name']) . ',
303 `pparent` = ' . $_REQUEST['new_pid'];
304 $result = mysql_query($sql) or die(" <pre>Workday->update__hours_from_form() BadSQL:\n$sql\n" . mysql_error());
305 $_REQUEST['new_subpid'] = mysql_insert_id();
306 }
307
308 $this->replacehours[$_REQUEST['new_subpid']] = $_REQUEST['new_pid_hours'];
309 }
310 }
311
312 function db_update($worker)
313 {
314 $wid = $worker->get_db_index();
315 $compid = $worker->get_employer();
316
317 if ( count($this->replacehours) ) {
318 while ( list($subpid, $hours) = each($this->replacehours) ) {
319 if ( $hours > 0 ) {
320 $pid = get_parent_for_subpid($subpid);
321 $sql = sprintf("
322 REPLACE %s
323 SET day = '%s',
324 worker = %d,
325 pid = %d,
326 worktype = 0,
327 hours = %f,
328 company = %d,
329 subpid = %d
330 ",
331 PTS_TBL_PROJECT_TIME, $this->daydate, $wid, $pid, hmin_to_db($hours), $compid, $subpid);
332 }
333 else {
334 $sql = sprintf("
335 DELETE FROM %s
336 WHERE day = '%s'
337 AND worker = %d
338 AND worktype = 0
339 AND subpid = %d
340 LIMIT 1",
341 PTS_TBL_PROJECT_TIME, $this->daydate, $wid, $subpid);
342 }
343 $result = mysql_query("$sql")or die(" <pre>WorkDay->db_update(): BadSQL:\n$sql\n".mysql_error());
344 }
345 }
346 }
347
348 function get_day_form($pid_list)
349 {
350
351 $info = "<table width=\"500\" bordercolor=\"#666666\" cellspacing=\"1\" bgcolor=\"#999999\" border=\"1\" noshade=\"noshade\">\n";
352 $info .= "<tr>\n<th>Projekt(e)</th>\n<th>Std.,Min.</th>\n</tr>\n";
353
354 if ( $this->numentries)
355 {
356 while(list($pindex, $pname) = each($this->pidnames)){
357 $info .= "<tr>\n<td align=\"center\"> \n";
358 $info .= sprintf("%s\n</td>\n", $pname);
359 $info .= sprintf("<td align=\"center\"><input type=\"text\" name=\"pid[%d]\" size=\"5\" value=\"%s\"></td>\n</tr>\n",
360 $pindex, min_to_hours(db_to_min($this->hours[$pindex])));
361 }
362 }
363
364 $script .= '
365 <script language="javascript">
366 <!--
367 function chooseMake(strFormName, boolHeadContained)
368 {
369 var arrModelList;
370 var objModelSelection;
371 var objMakeSelection;
372 var intOffSetForAll;
373 var i;
374
375 if (document.forms[strFormName].new_subpid == null)
376 return;
377
378 objModelSelection = document.forms[strFormName].new_subpid;
379 objMakeSelection = document.forms[strFormName].new_pid;
380 objModelSelection.selectedIndex = 0;
381 objModelSelection.options.length = 1;
382
383 if (boolHeadContained)
384 intOffsetForAll = 1;
385 else
386 intOffsetForAll = 0;
387
388
389 if (objMakeSelection.selectedIndex >= intOffsetForAll){
390 arrModelList = (arrModels[objMakeSelection.selectedIndex + 1 - intOffsetForAll]).split(\';\');
391 for (i = 0; i < arrModelList.length; i++){
392 objModelSelection.options.length = i+2;
393 objModelSelection.options[i+1].value = (arrModelList[i]).split(\',\')[0];
394 objModelSelection.options[i+1].text = (arrModelList[i]).split(\',\')[1];
395 }
396 }
397 } // chooseMake
398
399 // inhalt für die zweite selectbox ID,Name[;ID,Name[;ID,Name]...]
400
401 var arrModels = new Array();
402 ';
403
404 $info .= "<tr><td bgcolor=\"#000066\" align=\"center\"> <font color=\"#cccccc\"> <small>Neues Projekt hinzufügen</small></font><br />\n<select name=\"new_pid\" onChange=\"chooseMake('searchform', true);\">\n";
405 $info .= "<option value=\"\">Bitte wählen...</option>\n";
406 $i = 1;
407 while(list($key, $val) = each($pid_list)){
408 $subpid_list = list_subpids_for_pid($key);
409 $script_array_ = '';
410 if ( ! empty($subpid_list) ) {
411 foreach ( $subpid_list as $pindex => $pname )
412 $script_array_ .= "$pindex,$pname;";
413 $script_array .= "arrModels[$i] = '" . substr($script_array_,0,-1) . "';\n";
414 $i++;
415 if ($new_pid == $key)
416 $info .= sprintf("<option value=\"%d\" selected=\"selected\">%s</option>\n", $key, $val);
417 else
418 $info .= sprintf("<option value=\"%d\">%s</option>\n", $key, $val);
419 }
420
421 }
422
423 $script .= $script_array . "//--></script>";
424 $info .= "</select>\n";
425 $info .= "<select name=\"new_subpid\">\n";
426 $info .= "<option value=\"\">Bitte wählen...</option>\n";
427 $info .= "</select></td>\n";
428 $info .= "<td bgcolor=\"#000066\" align=\"center\"><input type=\"text\" name=\"new_pid_hours\" size=\"5\"></td></tr>\n";
429 $info .= "</table>\n";
430 $info .= $script;
431 return($info);
432 }
433
434 // PATCH LUCKE : BEGIN
435 function get_day_total() { return $this->totalhours; }
436 // PATCH LUCKE : END
437
438 function get_worktime(){
439 $work = substr($this->worktime["Kommt"],0,5)." Uhr<br />";
440 $work .= substr($this->worktime["Geht"],0,5)." Uhr<br />";
441 $work .= $this->worktime["Anz"] . " Std.";
442 return $work;
443 }
444
445 function get_day_info(){
446
447 $info = "<table bordercolor=\"#666666\" cellspacing=\"1\" BGCOLOR=\"#999999\" border=\"1\" noshade>\n<tr>\n";
448 $info .= "<th bgcolor=\"000066\"> <font color=\"CCCCCC\">Projekt</font></th>\n<th bgcolor=\"000066\"> <font color=\"CCCCCC\">Std.</font></th>\n</tr>\n";
449
450 if ($this->daytype[0] == 0){} //normaler Arbeitstag, nichts weiter
451 else
452 {
453 foreach ($this->daytype as $dt)
454 {
455 switch ($dt) {
456 case 0: break;
457 case 1: $info .= "<tr><td bgcolor=#ffcc66 colspan=2>Urlaub beantragt</td></tr>"; break;
458 case 2: $info .= "<tr><td bgcolor=#66cc66 colspan=2>Urlaub</td></tr>"; break;
459 case 3: $info .= "<tr><td bgcolor=#00e0ff colspan=2>Feiertag</td></tr>"; break;
460 case 4: $info .= "<tr><td bgcolor=#669966 colspan=2>Krank</td></tr>"; break;
461 case 5: $info .= "<tr><td bgcolor=#66cc66 colspan=2>halber Urlaubstag</td></tr>"; break;
462 case 6: $info .= "<tr><td bgcolor=#00e0ff colspan=2>halber *Feiertag*</td></tr>"; break;
463 default: break;
464 }
465 }
466 }
467
468 if($this->numentries){
469 while(list($key, $val) = each($this->pidnames)){
470 $info .= "<tr>\n<td> \n";
471 $info .= sprintf(" %s\n</td>\n<td align=\"center\">%s</td>\n</tr>\n",
472 $val, dbhm($this->hours[$key]));
473 }
474 }
475 $info .= "</table>\n";
476 return($info);
477 }
478
479 function set_daytype($wid){
480 $sql = sprintf("SELECT distinct worktype FROM %s WHERE day = '%s' AND (worker = %d OR worker = 0) ORDER BY worktype DESC",
481 PTS_TBL_PROJECT_TIME,$this->daydate, $wid);
482
483 $result = mysql_query("$sql")or die(" WorkDay-daytypeload(): BadSelect: $sql".mysql_error());
484
485 if ($result){
486 while($typ = mysql_fetch_row($result)){
487 $this->daytype[] = $typ[0];
488 }
489 }
490 else $this->daytype[0] = 0;
491 }
492
493
494 /* Sends an email notifing someone when the time is updated*/
495 function mail_notify($address, $fromaddr, $worker){
496
497 $subject = sprintf("Timesheet: hours updated for %s", $worker);
498 $message = sprintf("The worker %s updated their hours for %s",
499 $worker, $this->daydate);
500 mail($address, $subject, $message, "From: $fromaddr\nX-Mailer: PHP/" . phpversion());
501 }/*function mail_notify($address)*/
502 }/* class WorkDay */
503
504 ?>
Documentation generated on Fri, 26 Sep 2003 15:40:06 +0200 by phpDocumentor 1.2.2