PageRenderTime 58ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/modules/reports/class.weekreport.inc

https://github.com/klaaspeter/achievo
PHP | 880 lines | 680 code | 122 blank | 78 comment | 108 complexity | 179ecb45622a1ece538a72326531e07e MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. include_once("achievotools.inc");
  3. useattrib("atkdateattribute");
  4. atkImport("modules.utils.dateutil");
  5. define("ONEDAY", 24*60*60);
  6. define("ONEWEEK", 7*ONEDAY);
  7. class timeDisplayAttribute extends atkAttribute
  8. {
  9. function display($rec)
  10. {
  11. $time = $rec[$this->fieldName()];
  12. if (is_null($time==0)) return "";
  13. if ($time < 0) return sprintf("-%02d",(floor(abs($time)/60))).':'.sprintf("%02d",(abs($time)%60));
  14. return sprintf("%02d",floor($time/60)).':'.sprintf("%02d",$time%60);
  15. }
  16. }
  17. if(!function_exists("compare_by_field")) {
  18. function compare_by_field($a, $b, $field)
  19. {
  20. if ($a[$field]==$b[$field])
  21. {
  22. // equal items are always sorted by week
  23. if ($a["period"]==$b["period"]) return 0;
  24. return ($a["period"] < $b["period"]) ? -1 : 1;
  25. }
  26. return ($a[$field] < $b[$field]) ? -1 : 1;
  27. }
  28. }
  29. class weekreport extends atkNode
  30. {
  31. var $m_harvestedModules = null; //contains references to harvested modules
  32. var $m_harvestedColumns = null;
  33. var $m_overtimeActivities = null;
  34. function weekreport()
  35. {
  36. $this->atkNode("weekreport",NF_NO_ADD|NF_NO_DELETE|NF_NO_EDIT); // node() constructor is *not* called automatically!
  37. $this->add(new atkAttribute("userid"));
  38. $this->add(new atkAttribute("period"));
  39. $this->add(new atkAttribute("startdate"));
  40. $this->add(new atkAttribute("enddate"));
  41. $this->add(new timeDisplayAttribute("mon"));
  42. $this->add(new timeDisplayAttribute("tue"));
  43. $this->add(new timeDisplayAttribute("wed"));
  44. $this->add(new timeDisplayAttribute("thu"));
  45. $this->add(new timeDisplayAttribute("fri"));
  46. $this->add(new timeDisplayAttribute("sat"));
  47. $this->add(new timeDisplayAttribute("sun"));
  48. $db = &atkGetDb();
  49. $periods = $db->getRows("SELECT * FROM workperiod ORDER BY percentage");
  50. for($i=0;$i<count($periods);$i++)
  51. {
  52. $this->add(new timeDisplayAttribute($periods[$i]["name"], AF_TOTAL));
  53. }
  54. $this->add(new timeDisplayAttribute("overtimecompensation",AF_TOTAL));
  55. $this->addAdditionalColumns();
  56. $this->add(new timeDisplayAttribute("total",AF_TOTAL));
  57. $this->add(new timeDisplayAttribute("contract",AF_TOTAL));
  58. $this->add(new timeDisplayAttribute("overtime",AF_TOTAL));
  59. $this->add(new atkAttribute("balance"));
  60. $this->add(new atkAttribute("status"));
  61. }
  62. /**
  63. * Function for harvesting additional weekreport columns.
  64. * Beware: A column-name cannot exist more then once.
  65. */
  66. function addAdditionalColumns()
  67. {
  68. //retrieve additional weekreport columns ordered by module
  69. $this->harvestColumns();
  70. foreach($this->m_harvestedColumns as $module=>$columns)
  71. {
  72. foreach($columns as $col)
  73. {
  74. $attr = &$this->add(new timeDisplayAttribute($col, AF_TOTAL));
  75. /* @var $attr atkAttribute */
  76. $attr->setLabel(atktext($attr->fieldName(), $module));
  77. }
  78. }
  79. }
  80. function harvestColumns()
  81. {
  82. //only harvest if we haven't harvested yet.
  83. if($this->m_harvestedColumns == null)
  84. $this->m_harvestedColumns = atkHarvestModules("weekreport_getAdditionalColumns","",true);
  85. }
  86. function getOvertimeCompensationActivities()
  87. {
  88. if($this->m_overtimeActivities !== null)
  89. return;
  90. /* @var $db atkDb */
  91. $db = &atkGetDb();
  92. $query = $db->createQuery();
  93. $query->addField("id");
  94. $query->addTable("activity");
  95. $query->addCondition("overtimecompensation = 1");
  96. $this->m_overtimeActivities = $db->getrows($query->buildSelect());
  97. }
  98. function isOvertimeCompensationActivity($id)
  99. {
  100. $this->getOvertimeCompensationActivities();
  101. foreach($this->m_overtimeActivities as $item)
  102. {
  103. if($item["id"]==$id) return true;
  104. }
  105. return false;
  106. }
  107. function status_display($rec)
  108. {
  109. return atktext($rec["status"]);
  110. }
  111. function get_employee($user_id)
  112. {
  113. $db = &atkGetDb();
  114. $sql = "SELECT * FROM person WHERE status='active' AND id='".intval($user_id)."'";
  115. $record = $db->getrows($sql);
  116. return $record[0];
  117. }
  118. function get_employees($userid)
  119. {
  120. $harvest = atkHarvestModules("getEmpDropDown", '', true);
  121. if (is_array($harvest) && count($harvest) > 0)
  122. {
  123. if (moduleExists('advancedsecurity'))
  124. // $employee_code.='<OPTION VALUE="all">'.atktext("all_users").'</OPTION>';
  125. $employee_code .= $harvest['advancedsecurity'];
  126. }
  127. else
  128. {
  129. $db = &atkGetDb();
  130. $sql = "SELECT id, lastname,firstname,userid
  131. FROM person
  132. WHERE status='active' AND role = 'employee'
  133. ORDER BY lastname
  134. ";
  135. $records = $db->getrows($sql);
  136. $employee_code.='<OPTION VALUE="all">'.atktext("all_users").'</OPTION>';
  137. for($i=0;$i<count($records);$i++)
  138. {
  139. if ($userid==$records[$i]["id"]) $selected="selected";
  140. else $selected="";
  141. $employee_code.='<OPTION VALUE="'.$records[$i]["id"].'" '.$selected.'>'.$records[$i]["lastname"].', '.$records[$i]["firstname"].'</OPTION>';
  142. }
  143. }
  144. return $employee_code;
  145. }
  146. function balance_display($rec)
  147. {
  148. $node = &atkGetNode("timereg.overtime_balance");
  149. return $node->getOvertimeLink($rec);
  150. }
  151. function getHarvestedModuleObjects()
  152. {
  153. $this->harvestColumns();
  154. foreach($this->m_harvestedColumns as $module=>$columns)
  155. {
  156. $obj = &getModule($module);
  157. if(is_object($obj))
  158. {
  159. //If the modules have an initialise function, call it.
  160. if (method_exists($obj, "weekreport_init"))
  161. $obj->weekreport_init();
  162. $this->m_harvestedModules[$module] = $obj;
  163. }
  164. }
  165. }
  166. /**
  167. * One line description of the function
  168. *
  169. * @todo JvdW 12-01-2004 Oracle needs all columns not used in aggregate functions to be in the group by clause.
  170. * There might be more places in the code where this is true and need adjusting.
  171. * MySQL has an extended GROUP BY which doesn't need this according to the documentation:
  172. * "MySQL has extended the use of GROUP BY to allow you to select fields that are not mentioned in the GROUP BY clause.
  173. * If you are not getting the results you expect from your query, please read the GROUP BY description.
  174. * See section 6.3.7 Functions and Modifiers for Use with GROUP BY Clauses."
  175. *
  176. * @param type name description
  177. * @return type description
  178. */
  179. function collectData($nameswitch, $userid, $startdate, $enddate, $functionlevel_condition)
  180. {
  181. /* @var $db atkDb */
  182. $db = &atkGetDb();
  183. $query = $db->createQuery();
  184. $query->addField("time","", "hours");
  185. $query->addField("activityid", "", "hours");
  186. $query->addField("activitydate", "", "hours");
  187. $query->addField("userid", "", "hours");
  188. $query->addField("lastname", "", "person");
  189. $query->addField("firstname", "", "person");
  190. $query->addField("workperiod", "", "hours");
  191. $query->addTable("person");
  192. $query->addTable("hours");
  193. if ($nameswitch=="supervisor")
  194. {
  195. if($userid!="all") $query->addCondition("person.supervisor='$userid'");
  196. }
  197. else
  198. {
  199. if($userid!="all") $query->addCondition("hours.userid='$userid'");
  200. }
  201. $query->addCondition("hours.activitydate >= '$startdate'");
  202. $query->addCondition("hours.activitydate <= '$enddate'");
  203. $query->addCondition("hours.userid = person.id");
  204. $query->addCondition($functionlevel_condition);
  205. $query->addOrderBy("hours.userid, activitydate, person.lastname, person.firstname, workperiod");
  206. //@todo: addToWeekReportQuery() for each harvestedModule.
  207. $this->getHarvestedModuleObjects();
  208. if($this->m_harvestedModules!=null)
  209. {
  210. foreach($this->m_harvestedModules as $modulename=>$obj)
  211. {
  212. if (method_exists($obj, "weekreport_addToQuery"))
  213. $obj->weekreport_addToQuery($query);
  214. }
  215. }
  216. $rows = $db->getrows($query->buildSelect());
  217. return $rows;
  218. }
  219. /**
  220. * Get hours for selected user/supervisor (=manager)
  221. *
  222. * @param string $nameswitch all employees below 'supervisor' or 'name':selected user
  223. * @param int $user_id selected user
  224. * @param string $startdate
  225. * @param string $enddate
  226. * @param string $functionlevelswitch id of selected functionlevel
  227. * @param string $lowerlevels checkbox 'on' or 'off'
  228. * @return array $hourrecords
  229. */
  230. function getHourRecords($nameswitch, $user_id, $startdate, $enddate, $functionlevelswitch, $lowerlevels)
  231. {
  232. require_once(moduleDir('report').'utils/class.reportutils.inc');
  233. $repUtils = &atknew('report.utils.reportutils');
  234. $functionlevel_condition = $repUtils->getFunctionLevelCondition($functionlevelswitch, $lowerlevels);
  235. if ($nameswitch == 'supervisor')
  236. {
  237. $employees = $repUtils->getEmployeesArray($user_id); // get all users below this user
  238. $employees[]['id'] = $user_id; // add current user to employees
  239. $hourrecords = array();
  240. foreach ($employees as $employee)
  241. {
  242. $records = $this->collectData($nameswitch, $employee['id'], $startdate, $enddate, $functionlevel_condition);
  243. if (is_array($records) && count($records) > 0)
  244. {
  245. $hourrecords = array_merge($hourrecords, $records);
  246. }
  247. }
  248. }
  249. else
  250. {
  251. // not supervisor, get record for the selected user only
  252. $hourrecords = $this->collectData($nameswitch, $user_id, $startdate, $enddate, $functionlevel_condition);
  253. }
  254. return $hourrecords;
  255. }
  256. function getLocks($nameswitch, $userid, $report_start_week, $report_end_week)
  257. {
  258. $db = &atkGetDb();
  259. if ($nameswitch=="supervisor" && $userid!='all')
  260. {
  261. $query = "SELECT
  262. period, hours_lock.userid,hours_lock.approved
  263. FROM
  264. hours_lock, person
  265. WHERE
  266. ((hours_lock.userid = person.id AND person.supervisor='$userid')
  267. OR hours_lock.userid IS NULL OR hours_lock.userid='')
  268. AND
  269. period between '$report_start_week' and '$report_end_week' ";
  270. }
  271. else
  272. {
  273. // Collect locks..
  274. $query = "SELECT
  275. period, userid, approved
  276. FROM
  277. hours_lock
  278. WHERE
  279. period between '$report_start_week' and '$report_end_week' ";
  280. if ($nameswitch=="name"&&$userid!="all")
  281. {
  282. $query.="AND (userid = '$userid' OR userid IS NULL OR userid = '')";
  283. }
  284. }
  285. return $db->getrows($query);
  286. }
  287. function getStartdate()
  288. {
  289. $sessionmanager = &atkGetSessionManager();
  290. $startdate = $sessionmanager->pageVar("startdate");
  291. if (!isset($startdate)||$startdate=="") $startdate = date("Ymd" ,time()-(86400*7));
  292. if (is_string($startdate)) $startdate = str_replace("-", "", $startdate);
  293. if (is_array($startdate)) $startdate = dateutil::arr2str($startdate);
  294. $startdate = dateutil::startOfWeek($startdate);
  295. return dateutil::arr2str(dateutil::str2arr($startdate), "Y-m-d");
  296. }
  297. function getEnddate()
  298. {
  299. $sessionmanager = &atkGetSessionManager();
  300. $enddate = $sessionmanager->pageVar("enddate");
  301. if (!isset($enddate)||$enddate=="") $enddate = date("Ymd");
  302. if (is_string($enddate)) $enddate = str_replace("-", "", $enddate);
  303. if (is_array($enddate)) $enddate = dateutil::arr2str($enddate);
  304. $enddate = dateutil::endOfWeek($enddate);
  305. return dateutil::arr2str(dateutil::str2arr($enddate), "Y-m-d");
  306. }
  307. function action_report(&$handler)
  308. {
  309. global $g_user, $g_sessionManager;
  310. require_once(moduleDir('report').'utils/class.reportutils.inc');
  311. $repUtils = &atknew('report.utils.reportutils');
  312. $ui = &$this->getUi();
  313. $page = &$this->getPage();
  314. $this->addStyle("style.css");
  315. $atkorderby = $g_sessionManager->pageVar("atkorderby");
  316. $userid = $g_sessionManager->pageVar("userid");
  317. $employeeswitch = $g_sessionManager->pageVar("nameswitch");
  318. $showdetails = $g_sessionManager->pageVar("showdetails");
  319. $showstatus = $g_sessionManager->pageVar("showstatus");
  320. $functionlevelswitch = $g_sessionManager->pageVar("functionlevelswitch");
  321. if (moduleExists('advancedsecurity'))
  322. $lowerlevels = atkArrayNvl($this->m_postvars, "lowerlevels", 'off');
  323. else
  324. $lowerlevels = "off";
  325. /** $outputType gives control over the kind of output:
  326. * 0 standard(onscreen in compliance with theme, default)
  327. * 1 printable (onscreen in a format that easily can be printed on paper))
  328. * [was $printable]
  329. * 2 export ( to a file on local computer ex. achievo.csv)
  330. */
  331. $outputType = $g_sessionManager->pageVar("outputType");
  332. if (!isset($outputType)||$outputType=="") $outputType=0;
  333. if (!isset($atkorderby)||$atkorderby=="") $atkorderby = "period";
  334. $contentblocks = array();
  335. // $view_all = $g_securityManager->allowed('reports.weekreport','view_all');
  336. $view_all = $this->allowed('view_all');
  337. $view_managed = $this->allowed('view_managed');
  338. if (moduleExists('advancedsecurity'))
  339. $view_level = $this->allowed('view_level');
  340. else
  341. $view_level = false;
  342. $startdate = $this->getStartdate();
  343. $enddate = $this->getEnddate();
  344. if (!isset($userid)||$userid=="") $userid=$g_user["id"];
  345. if (!isset($employeeswitch)||$employeeswitch=="") $employeeswitch="name";
  346. if (!isset($showstatus)||$showstatus=="") $showstatus = "both";
  347. if ($outputType==0)
  348. {
  349. $output='<form action="'.getDispatchFile().'" method="get" id="entryform" name="entryform">';
  350. $output.='<input type="hidden" name="atknodetype" value="reports.weekreport">';
  351. $output.='<input type="hidden" name="atkaction" value="'.$this->m_action.'">';
  352. $data = array();
  353. $data[] = array('<b>'.atktext('sethoursfilter').'</b>');
  354. // we have to pass a 'dummy' record to the attributes to set their default value.
  355. $dummyrec = Array("startdate"=>array("year"=>substr($startdate,0,4),
  356. "month"=>substr($startdate,5,2),
  357. "day"=>substr($startdate,8,2)),
  358. "enddate"=>array("year"=>substr($enddate,0,4),
  359. "month"=>substr($enddate,5,2),
  360. "day"=>substr($enddate,8,2)));
  361. if($view_all)
  362. {
  363. $nameswitch = '<SELECT name="nameswitch"><OPTION VALUE="name">'.atktext("name").': <OPTION VALUE="supervisor" '.($employeeswitch=="supervisor"?"selected":"").'>'.atktext("supervisor").': </SELECT>';
  364. $users = ' <SELECT name="userid">'.$repUtils->get_employees($userid, true).'</SELECT>';
  365. }
  366. elseif($view_managed && !$view_level)
  367. {
  368. $nameswitch = '<SELECT name="nameswitch"><OPTION VALUE="name">'.atktext("name").': <OPTION VALUE="supervisor" '.($employeeswitch=="supervisor"?"selected":"").'>'.atktext("supervisor").': </SELECT>';
  369. $users = ' <SELECT name="userid">'.$repUtils->get_employees($userid).'</SELECT>';
  370. }
  371. elseif ($view_level)
  372. {
  373. $nameswitch = '<SELECT name="nameswitch"><OPTION VALUE="name">'.atktext("name").': <OPTION VALUE="supervisor" '.($employeeswitch=="supervisor"?"selected":"").'>'.atktext("supervisor").': </SELECT>';
  374. $users = ' <SELECT name="userid">'.$repUtils->getLevelEmployees($userid).'</SELECT>';
  375. }
  376. else
  377. {
  378. $userid = $g_user["id"];
  379. $users = $g_user["name"].'<input type="hidden" name="userid" value="'.$g_user["id"].'">';
  380. }
  381. $data[] = array($nameswitch,$users);
  382. $data[] = array(atktext('functionlevel','project').':',$repUtils->get_functionlevels($functionlevelswitch, $lowerlevels));
  383. $data[] = array('<hr>','<hr>');
  384. /*// TODO: Even if you don't have view_all right, you should still be able to view employees
  385. // that you supervise.
  386. if($view_all)
  387. {
  388. $data[] = array(atktext("supervisor"),'<SELECT name="supervisor">'.$this->get_supervisors($supervisor).'</SELECT>');
  389. } */
  390. $startdateatt = new atkDateAttribute("startdate","","", 0, date("Ymd"));
  391. $enddateatt = new atkDateAttribute("enddate","","", 0, atkConfig::get("timereg","timereg_allowfuture", false) ? 0 : date("Ymd"));
  392. $data[]= array(atktext("timespan"),$startdateatt->edit($dummyrec).' &nbsp;'.
  393. atktext("until").
  394. '&nbsp; '.$enddateatt->edit($dummyrec));
  395. $data[] = array(atktext("status"),'<select name="showstatus">
  396. <option VALUE="all" '.($showstatus=="all"?"selected":"").'>'.atktext("all").'
  397. <option VALUE="locked" '.($showstatus=="locked"?"selected":"").'>'.atktext("locked").'
  398. <option VALUE="unlocked" '.($showstatus=="unlocked"?"selected":"").'>'.atktext("unlocked").'
  399. <option VALUE="approved" '.($showstatus=="approved"?"selected":"").'>'.atktext("approved").'
  400. </select>');
  401. $data[] = array('<b>'.atktext("report_output_options").'</b>');
  402. $data[] = array(atktext("report_output_type"),'<select name="outputType">
  403. <option VALUE="0" selected>'.atktext("report_output_standard").'
  404. <option value="1">'.atktext("report_output_printable").'
  405. <option value="2">'.atktext("report_output_export").'
  406. </select>');
  407. $checked = ($showdetails==1) ? "checked" : "";
  408. $data[] = array(atktext("report_show_details"),'<input type="checkbox" class="atkcheckbox" name="showdetails" value="1" '.$checked.'>');
  409. $data[] = array(atktext("orderby"),'<select name="atkorderby">
  410. <option VALUE="period" '.($atkorderby=="period"?"selected":"").'>'.atktext("period").'
  411. <option VALUE="status" '.($atkorderby=="status"?"selected":"").'>'.atktext("status").'
  412. <option VALUE="userid" '.($atkorderby=="userid"?"selected":"").'>'.atktext("userid").'
  413. </select>');
  414. $tbl = &atknew("atk.utils.atktablerenderer");
  415. $tbl->setColSpan(0,0,2);
  416. $tbl->setColSpan(6,0,2);
  417. $output.=$tbl->render($data);
  418. $output.='<input type="submit" value="'.atktext("refresh").'"></form><br>';
  419. $tbl = &atknew("atk.utils.atktablerenderer");
  420. $contentblocks[] = $ui->renderBox(array("title"=>atktext("parameters"),"content"=>$output));
  421. }
  422. // If we haven't got a userid by now, don't display the report
  423. $rldata = null;
  424. if ($userid!="")
  425. {
  426. $weekdata = array();
  427. // first fill the weeks and start/end dates..
  428. $startstamp = adodb_mktime(12,0,0,substr($startdate,5,2),
  429. substr($startdate,8,2),
  430. substr($startdate,0,4));
  431. $endstamp = adodb_mktime(12,0,0,substr($enddate,5,2),
  432. substr($enddate,8,2),
  433. substr($enddate,0,4));
  434. // overzicht moet beginnen op de eerste dag van de week van de gekozen datum.
  435. $realweekstart = startOfWeek($startdate);
  436. $realstartstamp = adodb_mktime(12,0,0,substr($realweekstart,5,2),
  437. substr($realweekstart,8,2),
  438. substr($realweekstart,0,4));
  439. $nrofdays = ceil(($endstamp-$realstartstamp)/(ONEDAY));
  440. for ($i=0;$i<=$nrofdays;$i++)
  441. {
  442. $curstamp = $realstartstamp + (ONEDAY*$i);
  443. if (strftime("%w",$curstamp)==1)
  444. {
  445. $key = weekstamp($curstamp);
  446. $weekdata[$key]["period"] = $key;
  447. $weekdata[$key]["startdate"] = strftime("%d-%m-%Y",$curstamp);
  448. $weekdata[$key]["enddate"] = strftime("%d-%m-%Y",$curstamp+(6*ONEDAY));
  449. $i+=6;
  450. }
  451. }
  452. $report_start_week = weekstamp($startstamp);
  453. $report_end_week = weekstamp($endstamp);
  454. // determine employee names and contracts..
  455. $query = "SELECT
  456. id, lastname, firstname
  457. FROM
  458. person
  459. WHERE role='employee' AND status='active' ";
  460. if ($employeeswitch=="supervisor" && $userid!="all")
  461. {
  462. $query.= "AND supervisor = '".$userid."' ";
  463. }
  464. elseif ($employeeswitch=="name" && $userid!="all")
  465. {
  466. $query.= "AND id = '".$userid."'";
  467. }
  468. $db = &atkGetDb();
  469. $persons = $db->getrows($query);
  470. $end = endOfWeek(date("Y-m-d", $endstamp));
  471. $newendstamp = adodb_mktime(0,0,0,substr($end,5,2),substr($end,8,2)+1,substr($end,0,4));
  472. $balancenode = &atkGetNode("timereg.overtime_balance");
  473. for ($j=$startstamp;$j<=$newendstamp;$j+=ONEWEEK)
  474. {
  475. $weekstamp = weekstamp($j);
  476. $start_week = date("Y-m-d", adodb_mktime(12,0,0,substr($weekdata[$weekstamp]["startdate"],3,2),
  477. substr($weekdata[$weekstamp]["startdate"],0,2),
  478. substr($weekdata[$weekstamp]["startdate"],6,4)));
  479. $end_week = date("Y-m-d", adodb_mktime(12,0,0,substr($weekdata[$weekstamp]["enddate"],3,2),
  480. substr($weekdata[$weekstamp]["enddate"],0,2),
  481. substr($weekdata[$weekstamp]["enddate"],6,4)));
  482. $weekdata[$weekstamp]["period"] = $weekstamp;
  483. foreach($persons as $person)
  484. {
  485. $weekdata[$weekstamp]["userdata"][$person["id"]]["name"] = $person["lastname"].", ".$person["firstname"];
  486. if(!array_key_exists('contract',$weekdata[$weekstamp]["userdata"][$person["id"]]))
  487. $weekdata[$weekstamp]["userdata"][$person["id"]]['contract']=0;
  488. $weekdata[$weekstamp]["userdata"][$person["id"]]["contract"] += ($balancenode->getContractHours($start_week, $end_week, $person["id"]) * 60);
  489. }
  490. }
  491. $periods = $db->getRows("SELECT * FROM workperiod");
  492. $periodids = array();
  493. foreach($periods as $period)
  494. $periodids[] = $period["id"];
  495. $strdow = array("sun","mon","tue","wed","thu","fri","sat");
  496. // collect data..
  497. $raw = $this->getHourRecords($employeeswitch, $userid, $startdate, $enddate, $functionlevelswitch, $lowerlevels);
  498. $this->getHarvestedModuleObjects();
  499. $users_array = array();
  500. for ($i=0,$_i=count($raw);$i<$_i;$i++)
  501. {
  502. //is this timeregistration a overtimecompensation?
  503. $isovertimecompensation = $this->isOvertimeCompensationActivity($raw[$i]["activityid"]);
  504. $stamp = adodb_mktime(12,0,0,substr($raw[$i]["activitydate"],5,2),
  505. substr($raw[$i]["activitydate"],8,2),
  506. substr($raw[$i]["activitydate"],0,4));
  507. $dow = strftime("%w",$stamp);
  508. $key = weekstamp($stamp);
  509. $weekdata[$key]["period"] = $key;
  510. $uid = $raw[$i]["userid"];
  511. $users_array[] = $uid;
  512. $workperiod = in_array($raw[$i]["workperiod"], $periodids) ? $raw[$i]["workperiod"] : "unknownperiod";
  513. if(!array_key_exists($uid,$weekdata[$key]['userdata']))
  514. {
  515. $weekdata[$key]['userdata'][$uid] = array();
  516. }
  517. if(!array_key_exists($workperiod,$weekdata[$key]['userdata'][$uid]))
  518. $weekdata[$key]['userdata'][$uid][$workperiod] = 0;
  519. if(!array_key_exists($strdow[$dow],$weekdata[$key]['userdata'][$uid]))
  520. $weekdata[$key]['userdata'][$uid][$strdow[$dow]] = 0;
  521. if(!array_key_exists('overtimecompensation',$weekdata[$key]['userdata'][$uid]))
  522. $weekdata[$key]['userdata'][$uid]['overtimecompensation']=0;
  523. if(!array_key_exists('total',$weekdata[$key]['userdata'][$uid]))
  524. $weekdata[$key]['userdata'][$uid]['total']=0;
  525. $weekdata[$key]["userdata"][$uid][$strdow[$dow]] += $raw[$i]["time"];
  526. $weekdata[$key]["userdata"][$uid][$workperiod] += $raw[$i]["time"];
  527. //we do not add overtimecompensation hours to the total
  528. if($isovertimecompensation)
  529. $weekdata[$key]["userdata"][$uid]["overtimecompensation"] += $raw[$i]["time"];
  530. else
  531. $weekdata[$key]["userdata"][$uid]["total"] += $raw[$i]["time"];
  532. //Check for each column if the record should be added to it.
  533. //Each module can determine this on its own.
  534. foreach($this->m_harvestedColumns as $modulename=>$columns)
  535. {
  536. //get the module object
  537. $obj = $this->m_harvestedModules[$modulename];
  538. if(method_exists($obj,"weekreport_addToColumn"))
  539. {
  540. foreach($columns as $col)
  541. {
  542. if($obj->weekreport_addToColumn($raw[$i],$col))
  543. $weekdata[$key]["userdata"][$uid][$col] += $raw[$i]["time"];
  544. }
  545. }
  546. }
  547. $weekdata[$key]["userdata"][$uid]["name"] = $raw[$i]["lastname"].", ".$raw[$i]["firstname"];
  548. // We need to display the first date and last date of each week.
  549. // Since we are looping days now, it is easiest if we calculate the
  550. // beginning of a week here.
  551. }
  552. $locks = $this->getLocks($employeeswitch, $userid, $report_start_week, $report_end_week);
  553. for($i=0,$_i=count($locks);$i<$_i;$i++)
  554. {
  555. if($locks[$i]["approved"]==1)
  556. {
  557. $status = "approved";
  558. }
  559. else
  560. {
  561. $status = "locked";
  562. }
  563. if ($locks[$i]["userid"]=="" || $locks[$i]["userid"]==0)
  564. {
  565. // Lock is for all users
  566. foreach($users_array as $uid)
  567. {
  568. $weekdata[$locks[$i]["period"]]["userdata"][$uid]["status"]=$status;
  569. }
  570. }
  571. else
  572. {
  573. $weekdata[$locks[$i]["period"]]["userdata"][$locks[$i]["userid"]]["status"]=$status;
  574. }
  575. }
  576. // weekdata is an associative array, indexed by weeknumber.
  577. // it must be converted to a normal array in order to be usable
  578. // by recordlist functions.
  579. // we also need to calculate some numbers.
  580. $rldata = array();
  581. foreach ($weekdata as $weeknr => $data)
  582. {
  583. $record = array();
  584. $record["startdate"] = $data["startdate"];
  585. $record["enddate"] = $data["enddate"];
  586. $record["period"] = $data["period"];
  587. $record["status"] = (array_key_exists('status',$data)?$data["status"]:'');
  588. if (is_array($data["userdata"]))
  589. {
  590. foreach($data["userdata"] as $user => $userdata)
  591. {
  592. $record["userid"] = $userdata["name"];
  593. $record["balance"] = $balancenode->getBalance(date("Y-m-d", adodb_mktime(0,0,0,substr($data["enddate"],3,2),substr($data["enddate"],0,2),substr($data["enddate"],6,4))), $user);
  594. $record["balance"]["outputtype"] = $outputType;
  595. $newtotal = 0;
  596. //count total hours of working periods
  597. for($i=0,$_i=count($periods);$i<$_i;$i++)
  598. {
  599. if(array_key_exists($periods[$i]['id'],$userdata))
  600. {
  601. $value = $userdata[$periods[$i]["id"]];
  602. }
  603. else
  604. {
  605. $value=0;
  606. }
  607. $record[$periods[$i]["name"]] = $value;
  608. $newtotal += ($periods[$i]["percentage"]/100) * $value;
  609. }
  610. if(array_key_exists('unknownperiod',$userdata))
  611. $newtotal += $userdata["unknownperiod"];
  612. if ($newtotal == 0 && array_key_exists('total',$userdata)) $newtotal = $userdata["total"];
  613. //subtract overtimecompensation hours from newtotal
  614. $newtotal -= (array_key_exists('overtimecompensation',$userdata)?$userdata["overtimecompensation"]:0);
  615. $record["overtimecompensation"] = (array_key_exists('overtimecompensation',$userdata)?$userdata["overtimecompensation"]:0);
  616. $record["total"] = (array_key_exists('total',$userdata)?$userdata["total"]:0);
  617. $record["contract"] = $userdata["contract"];
  618. $record["overtime"] = $newtotal-$userdata["contract"];
  619. //The additional columns must be added to the record,
  620. //so they are rendered.
  621. foreach($this->m_harvestedColumns as $modulename=>$columns)
  622. {
  623. foreach($columns as $col)
  624. $record[$col] = $userdata[$col];
  625. }
  626. if (array_key_exists('status',$userdata) && $userdata["status"]!="")
  627. {
  628. $record["status"] = $userdata["status"];
  629. }
  630. else
  631. {
  632. $record["status"] = (array_key_exists('status',$data)?$data["status"]:'');
  633. }
  634. if($record["status"]=="locked")
  635. {
  636. $cmpstatus = "locked";
  637. }
  638. elseif($record["status"]=="approved")
  639. {
  640. $cmpstatus = "approved";
  641. }
  642. else
  643. {
  644. $cmpstatus = "unlocked";
  645. }
  646. if ($showstatus=="all" || $cmpstatus==$showstatus)
  647. {
  648. for($i=0,$_i=count($strdow);$i<$_i;$i++)
  649. {
  650. if(array_key_exists($strdow[$i],$userdata))
  651. $record[$strdow[$i]] = $userdata[$strdow[$i]];
  652. }
  653. $rldata[] = $record;
  654. }
  655. }
  656. }
  657. }
  658. // sorting..
  659. if ($atkorderby=="") $atkorderby = "period";
  660. list($field, $desc) = explode(' ', $atkorderby);
  661. $func = create_function('$a, $b', 'return compare_by_field('.($desc != null ? '$b, $a' : '$a, $b').', "'.$field.'");');
  662. if (function_exists($func))
  663. usort($rldata, $func);
  664. if ($showdetails==1)
  665. {
  666. $suppress = array(); // show all columns
  667. }
  668. else
  669. {
  670. $suppress = $strdow; // suppress day details
  671. $suppress[] = "startdate";
  672. $suppress[] = "enddate";
  673. }
  674. if ($employeeswitch=="name" && $userid!="all") $suppress[] = "userid";
  675. }
  676. //OVERTIMEBALANCEDEBUGGING START
  677. if ($employeeswitch=="name" && $userid!="all" && atkConfig::get("timereg","overtimebalancedebugging") && atkConfig("debug") > 0)
  678. {
  679. atkimport("modules.utils.dateutil",false);
  680. $prestamp = date("Y-m-d", adodb_mktime(0,0,0,substr($rldata[0]["enddate"],3,2),substr($rldata[0]["enddate"],0,2),substr($rldata[0]["enddate"],6,4)) - (7 * 86400));
  681. $prebalance = $balancenode->getBalance($prestamp, $userid);
  682. $totalhours = 0;
  683. $totalcontract = 0;
  684. $prevbalance = $prebalance["balance"];
  685. foreach($rldata as $rec)
  686. {
  687. $totalhours += $rec["total"];
  688. $totalcontract += $rec["contract"];
  689. $week = $rec["period"];
  690. $shouldhaveovertime = $rec["total"] - $rec["contract"];
  691. if (round($shouldhaveovertime) != round($rec["overtime"]))
  692. {
  693. atkerror("In week $week, overtime should be $shouldhaveovertime");
  694. }
  695. if (isset($prevbalance))
  696. {
  697. $diff = ($rec["balance"]["balance"] - $prevbalance) * 60;
  698. if (round($shouldhaveovertime) != round($diff))
  699. {
  700. atkerror("In week $week, the balance should be $shouldhaveovertime higher than the previous balance ".($prevbalance*60).", but it is $diff higher");
  701. }
  702. if (round(($prevbalance * 60) + $shouldhaveovertime) != round($rec["balance"]["balance"] * 60))
  703. {
  704. atkerror("In week $week, the balance should be " . ($prevbalance * 60) . " + " . $shouldhaveovertime . " = " . (($prevbalance * 60) + $shouldhaveovertime) . " but it is calculated to be " . ($rec["balance"]["balance"] * 60));
  705. }
  706. }
  707. $prevbalance = $rec["balance"]["balance"];
  708. }
  709. $postbalance = $rldata[count($rldata)-1]["balance"];
  710. $balancediff = $postbalance["balance"] - $prebalance["balance"];
  711. $shouldhavebalancediff = $totalhours - $totalcontract;
  712. if (round($shouldhavebalancediff) != round($balancediff * 60))
  713. {
  714. atkerror("Overall balance mutation should be $totalhours - $totalcontract = $shouldhavebalancediff, but it is " . ($balancediff * 60));
  715. }
  716. }
  717. if ($outputType=="0")
  718. {
  719. if ($userid!="all")
  720. {
  721. $emprec = $this->get_employee($userid);
  722. if ($employeeswitch=="supervisor")
  723. {
  724. $label = atktext("supervisor");
  725. }
  726. else
  727. {
  728. $label = atktext("name");
  729. }
  730. $data = array();
  731. $data[] = array($label.": ",$emprec["lastname"].", ".$emprec["firstname"]);
  732. $data[] = array(atktext("email").": ",$emprec["email"]);
  733. }
  734. if(!is_null($rldata))
  735. {
  736. $tbl = &atknew("atk.utils.atktablerenderer");
  737. $output = $tbl->render($data);
  738. $rl = &atknew("atk.recordlist.atkrecordlist");
  739. $output.='<br>'.$rl->render($this, $rldata, array(),false,$suppress,"rlform",array(),"","rlform");
  740. $contentblocks[] = $ui->renderBox(array("title"=>atktext("weekreport")." ".atktext("report_intimespan")." ".$startdate." t/m ".$enddate,"content"=>$output));
  741. }
  742. $actionpage = $this->renderActionPage("admin", $contentblocks);
  743. $page->addContent($actionpage);
  744. }
  745. else if ($outputType=="1")
  746. {
  747. $rl = &atknew("atk.recordlist.atkcustomrecordlist");
  748. $page->addContent($rl->render($this, $rldata,"<tr>","<td>","</td>","</tr>", "0","",$suppress));
  749. }
  750. else if ($outputType=="2")
  751. {
  752. // special RecordList can export to file
  753. $rl = &atknew("atk.recordlist.atkcustomrecordlist");
  754. $rl->render($this, $rldata, "", '"', '";', "\r\n", "1", "",$suppress);
  755. }
  756. }
  757. }
  758. ?>