1<?php 2 3/** 4 * OrangeHRM is a comprehensive Human Resource Management (HRM) System that captures 5 * all the essential functionalities required for any enterprise. 6 * Copyright (C) 2006 OrangeHRM Inc., http://www.orangehrm.com 7 * 8 * OrangeHRM is free software; you can redistribute it and/or modify it under the terms of 9 * the GNU General Public License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * OrangeHRM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along with this program; 17 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA 19 */ 20 21class EmployeeDirectoryDao extends BaseDao{ 22 23 /** 24 * Mapping of search field names to database fields 25 * @var array 26 */ 27 protected static $searchMapping = array( 28 'id' => 'e.employee_id', 29 'employee_name' => 'concat_ws(\' \', e.emp_firstname,e.emp_middle_name,e.emp_lastname)', 30 'middleName' => 'e.emp_middle_name', 31 'lastName' => 'e.emp_lastName', 32 'job_title' => 'j.job_title', 33 'emp_work_telephone' => 'e.emp_work_telephone', 34 'emp_work_email' => 'e.emp_work_email', 35 'employee_status' => 'es.estat_name', 36 'sub_unit' => 'cs.name', 37 'termination' => 'e.termination_id', 38 'location' => 'l.location_id', 39 'employee_id_list' => 'e.emp_number', 40 ); 41 42 /** 43 * Mapping of sort field names to database fields 44 * @var array 45 */ 46 protected static $sortMapping = array( 47 'firstName' => 'e.emp_firstname', 48 'middleName' => 'e.emp_middle_name', 49 'firstMiddleName' => array('e.emp_firstname','e.emp_middle_name'), 50 'lastName' => 'e.emp_lastName', 51 'fullName' => array('e.emp_firstname', 'e.emp_middle_name', 'e.emp_lastName'), 52 'jobTitle' => 'j.job_title', 53 'empLocation' => 'loc.name', 54 'employeeStatus' => 'es.name', 55 'subDivision' => 'cs.name', 56 ); 57 58 /** 59 * Get employee list after sorting and filtering using given parameters. 60 * 61 * @param array $sortField 62 * @param $sortOrder 63 * @param $filters 64 * @return array 65 */ 66 public function getSearchEmployeeCount(array $filters = null) { 67 68 $select = ''; 69 $query = ''; 70 $bindParams = array(); 71 $orderBy = ''; 72 73 $this->_getEmployeeListQuery($select, $query, $bindParams, $orderBy, null, null, $filters); 74 75 $countQuery = 'SELECT COUNT(*) FROM (' . $select . ' ' . $query . ' ) AS countqry'; 76 77 if (sfConfig::get('sf_logging_enabled')) { 78 $msg = 'COUNT: ' . $countQuery; 79 if (count($bindParams) > 0 ) { 80 $msg .= ' (' . implode(',', $bindParams) . ')'; 81 } 82 sfContext::getInstance()->getLogger()->info($msg); 83 } 84 85 $conn = Doctrine_Manager::connection(); 86 $statement = $conn->prepare($countQuery); 87 $result = $statement->execute($bindParams); 88 $count = 0; 89 if ($result) { 90 if ($statement->rowCount() > 0) { 91 $count = $statement->fetchColumn(); 92 } 93 } 94 95 return $count; 96 } 97 98 /** 99 * Get SQL Query which can be used fetch employee list with the given 100 * sorting and filtering options 101 * 102 * @param &$select select part of query 103 * @param &$query query 104 * @param &$bindParams bind params for query 105 * @param &$orderBy order by part of query 106 * @param array $sortField 107 * @param $sortOrder 108 * @param $filters 109 * @return none 110 */ 111 private function _getEmployeeListQuery(&$select, &$query, array &$bindParams, &$orderBy, 112 $sortField = null, $sortOrder = null, array $filters = null) { 113 114 $searchByTerminated = EmployeeSearchForm::WITHOUT_TERMINATED; 115 116 /* 117 * Using direct SQL since it is difficult to use Doctrine DQL or RawSQL to get an efficient 118 * query taht searches the company structure tree and supervisors. 119 */ 120 121 122 123 $select = 'SELECT e.emp_number AS empNumber, e.employee_id AS employeeId, ' . 124 'e.emp_firstname AS firstName, e.emp_lastname AS lastName, ' . 125 'e.emp_middle_name AS middleName, e.termination_id AS terminationId, ' . 126 'cs.name AS subDivision, cs.id AS subDivisionId,' . 127 'j.job_title AS jobTitle, j.id AS jobTitleId, j.is_deleted AS isDeleted, ' . 128 'es.name AS employeeStatus, es.id AS employeeStatusId, '. 129 'e.emp_hm_telephone, e.emp_mobile, e.emp_work_telephone, e.emp_work_email, e.emp_oth_email, '. 130 131 'GROUP_CONCAT(DISTINCT loc.id, \'##\',loc.name) AS locationIds'; 132 133 134 $query = 'FROM hs_hr_employee e ' . 135 ' LEFT JOIN ohrm_subunit cs ON cs.id = e.work_station ' . 136 ' LEFT JOIN ohrm_job_title j on j.id = e.job_title_code ' . 137 ' LEFT JOIN ohrm_employment_status es on e.emp_status = es.id ' . 138 ' LEFT JOIN hs_hr_emp_locations l ON l.emp_number = e.emp_number ' . 139 ' LEFT JOIN ohrm_location loc ON l.location_id = loc.id'; 140 141 /* search filters */ 142 $conditions = array(); 143 144 if (!empty($filters)) { 145 146 $filterCount = 0; 147 148 foreach ($filters as $searchField=>$searchBy ) { 149 if (!empty($searchField) && !empty($searchBy) 150 && array_key_exists($searchField, self::$searchMapping) ) { 151 $field = self::$searchMapping[$searchField]; 152 153 if ($searchField == 'sub_unit') { 154 155 /* 156 * Not efficient if searching substations by more than one value, but 157 * we only have the facility to search by one value in the UI. 158 */ 159 $conditions[] = 'e.work_station IN (SELECT n.id FROM ohrm_subunit n ' . 160 'INNER JOIN ohrm_subunit p WHERE n.lft >= p.lft ' . 161 'AND n.rgt <= p.rgt AND p.id = ? )'; 162 $bindParams[] = $searchBy; 163 } else if ($searchField == 'id') { 164 $conditions[] = ' e.employee_id LIKE ? '; 165 $bindParams[] = $searchBy; 166 } else if ($searchField == 'job_title') { 167 $conditions[] = ' j.id = ? '; 168 $bindParams[] = $searchBy; 169 } else if ($searchField == 'employee_status') { 170 $conditions[] = ' es.id = ? '; 171 $bindParams[] = $searchBy; 172 } else if ($searchField == 'employee_id_list') { 173 $conditions[] = ' e.emp_number IN (' . implode(',', $searchBy) . ') '; 174 } else if ($searchField == 'employee_name') { 175 $conditions[] = $field . ' LIKE ? '; 176 // Replace multiple spaces in string with wildcards 177 $value = preg_replace('!\s+!', '%', $searchBy); 178 $bindParams[] = '%' . $value . '%'; 179 }elseif( $searchField == 'location' ){ 180 //print_r($filters['location']); 181 182 $locIds = $filters['location']; 183 $idArray = explode(',', $locIds); 184 185 if($idArray[0] > 0){ 186 $conditions[] = ' l.location_id IN (' . $searchBy . ') '; 187 188 } 189 } 190 191 $filterCount++; 192 193 if ($searchField == 'termination') { 194 $searchByTerminated = $searchBy; 195 } 196 } 197 } 198 } 199 200 /* If not searching by employee status, hide terminated employees */ 201 if ($searchByTerminated == EmployeeSearchForm::WITHOUT_TERMINATED) { 202 $conditions[] = "( e.termination_id IS NULL )"; 203 } 204 205 if ($searchByTerminated == EmployeeSearchForm::ONLY_TERMINATED) { 206 $conditions[] = "( e.termination_id IS NOT NULL )"; 207 } 208 209 /* Build the query */ 210 $numConditions = 0; 211 foreach ($conditions as $condition) { 212 $numConditions++; 213 214 if ($numConditions == 1) { 215 $query .= ' WHERE ' . $condition; 216 } else { 217 $query .= ' AND ' . $condition; 218 } 219 } 220 221 /* Group by */ 222 $query .= ' GROUP BY e.emp_number '; 223 224 /* sorting */ 225 $order = array(); 226 227 if( !empty($sortField) && !empty($sortOrder) ) { 228 if( array_key_exists($sortField, self::$sortMapping) ) { 229 $field = self::$sortMapping[$sortField]; 230 if (is_array($field)) { 231 foreach ($field as $name) { 232 $order[$name] = $sortOrder; 233 } 234 } else { 235 $order[$field] = $sortOrder; 236 } 237 } 238 } 239 240 /* Default sort by emp_number, makes resulting order predictable, useful for testing */ 241 $order['e.emp_lastname'] = 'asc'; 242 243 $order['e.emp_number'] = 'asc'; 244 245 /* Build the order by part */ 246 $numOrderBy = 0; 247 foreach ($order as $field=>$dir) { 248 $numOrderBy++; 249 if ($numOrderBy == 1) { 250 $orderBy = ' ORDER BY ' . $field . ' ' . $dir; 251 } else { 252 $orderBy .= ', ' . $field . ' ' . $dir; 253 } 254 } 255 256 } 257 258 259 260 /** 261 * Get employee list after sorting and filtering using given parameters. 262 * 263 * @param EmployeeSearchParameterHolder $parameterHolder 264 */ 265 public function searchEmployees(EmployeeSearchParameterHolder $parameterHolder) { 266 267 $sortField = $parameterHolder->getOrderField(); 268 $sortOrder = $parameterHolder->getOrderBy(); 269 $offset = $parameterHolder->getOffset(); 270 $limit = $parameterHolder->getLimit(); 271 $filters = $parameterHolder->getFilters(); 272 $returnType = $parameterHolder->getReturnType(); 273 274 $select = ''; 275 $query = ''; 276 $bindParams = array(); 277 $orderBy = ''; 278 279 $this->_getEmployeeListQuery($select, $query, $bindParams, $orderBy, 280 $sortField, $sortOrder, $filters); 281 282 $completeQuery = $select . ' ' . $query . ' ' . $orderBy; 283 284 if (!is_null($offset) && !is_null($limit)) { 285 $completeQuery .= ' LIMIT ' . $offset . ', ' . $limit; 286 } 287 288 if (sfConfig::get('sf_logging_enabled')) { 289 $msg = $completeQuery; 290 if (count($bindParams) > 0 ) { 291 $msg .= ' (' . implode(',', $bindParams) . ')'; 292 } 293 sfContext::getInstance()->getLogger()->info($msg); 294 } 295//print_r($completeQuery); 296//print_r($bindParams); 297 $conn = Doctrine_Manager::connection(); 298 $statement = $conn->prepare($completeQuery); 299 $result = $statement->execute($bindParams); 300 301 if ($returnType == EmployeeSearchParameterHolder::RETURN_TYPE_OBJECT) { 302 $employees = new Doctrine_Collection(Doctrine::getTable('Employee')); 303 304 if ($result) { 305 while ($row = $statement->fetch() ) { 306 //print_r(); 307 $employee = new Employee(); 308 309 $employee->setEmpNumber($row['empNumber']); 310 $employee->setEmployeeId($row['employeeId']); 311 $employee->setFirstName($row['firstName']); 312 $employee->setMiddleName($row['middleName']); 313 $employee->setLastName($row['lastName']); 314 $employee->setTerminationId($row['terminationId']); 315 $employee->setEmpHmTelephone($row['emp_hm_telephone']); 316 $employee->setEmpMobile($row['emp_mobile']); 317 $employee->setEmpWorkTelephone($row['emp_work_telephone']); 318 $employee->setEmpWorkEmail($row['emp_work_email']); 319 $employee->setEmpOthEmail($row['emp_oth_email']); 320 321 $jobTitle = new JobTitle(); 322 $jobTitle->setId($row['jobTitleId']); 323 $jobTitle->setJobTitleName($row['jobTitle']); 324 $jobTitle->setIsDeleted($row['isDeleted']); 325 $employee->setJobTitle($jobTitle); 326 327 $employeeStatus = new EmploymentStatus(); 328 $employeeStatus->setId($row['employeeStatusId']); 329 $employeeStatus->setName($row['employeeStatus']); 330 $employee->setEmployeeStatus($employeeStatus); 331 332 $workStation = new SubUnit(); 333 $workStation->setName($row['subDivision']); 334 $workStation->setId($row['subDivisionId']); 335 $employee->setSubDivision($workStation); 336 337 $supervisorList = isset($row['supervisors'])?$row['supervisors']:''; 338 339 if (!empty($supervisorList)) { 340 341 $supervisors = new Doctrine_Collection(Doctrine::getTable('Employee')); 342 343 $supervisorArray = explode(',', $supervisorList); 344 foreach ($supervisorArray as $supervisor) { 345 list($first, $middle, $last) = explode('##', $supervisor); 346 $supervisor = new Employee(); 347 $supervisor->setFirstName($first); 348 $supervisor->setMiddleName($middle); 349 $supervisor->setLastName($last); 350 $employee->supervisors[] = $supervisor; 351 } 352 } 353 354 $locationList = $row['locationIds']; 355 356 if (!empty($locationList)) { 357 358 // $locations = new Doctrine_Collection(Doctrine::getTable('EmpLocations')); 359 360 $locationArray = explode(',', $locationList); 361 foreach ($locationArray as $location) { 362 list($id, $name) = explode('##', $location); 363 $empLocation = new Location(); 364 $empLocation->setId($id); 365 $empLocation->setName($name); 366 $employee->locations[] = $empLocation; 367 } 368 } 369 370 $employees[] = $employee; 371 } 372 } 373 } 374 else { 375 return $statement->fetchAll(); 376 } 377 return $employees; 378 379 } 380 381}