Release note v16.0

------------------
### Features
 * Advanced Employee Management Module is now included in IceHrm Open Source Edition
 * LDAP Module which was only available in IceHrm Enterprise is now included in open source also
 * Initial implementation of icehrm REST Api for reading employee details
 * Improvements to data filtering
 * Multiple tabs for settings module
 * Overtime reports - now its possible to calculate overtime for employees.compatible with US overtime rules
 * Logout the user if tried accessing an unauthorized module
 * Setting for updating module names

### Fixes
 * Fix issue: classes should be loaded even the module is disabled
 * Deleting the only Admin user is not allowed
 * Fixes for handling non UTF-8
 * Fix for non-mandatory select boxes are shown as mandatory
This commit is contained in:
Thilina Hasantha
2016-04-15 20:24:39 +05:30
parent 301ea64832
commit 31bb455d6f
71 changed files with 7322 additions and 2813 deletions

View File

@@ -0,0 +1,164 @@
<?php
class EmployeesActionManager extends SubActionManager{
public function terminateEmployee($req){
$employee = new Employee();
$employee->Load("id = ?",array($req->id));
if(empty($employee->id)){
return new IceResponse(IceResponse::ERROR, "Employee Not Found");
}
$employee->termination_date = date('Y-m-d H:i:s');
$employee->status = 'Terminated';
$ok = $employee->Save();
if(!$ok){
return new IceResponse(IceResponse::ERROR, "Error occured while terminating employee");
}
return new IceResponse(IceResponse::SUCCESS, $employee);
//$user = BaseService::getInstance()->getUserFromProfileId($employee->id);
}
public function activateEmployee($req){
$employee = new Employee();
$employee->Load("id = ?",array($req->id));
if(empty($employee->id)){
return new IceResponse(IceResponse::ERROR, "Employee Not Found");
}
$employee->termination_date = NULL;
$employee->status = 'Active';
$ok = $employee->Save();
if(!$ok){
return new IceResponse(IceResponse::ERROR, "Error occured while activating employee");
}
return new IceResponse(IceResponse::SUCCESS, $employee);
//$user = BaseService::getInstance()->getUserFromProfileId($employee->id);
}
public function deleteEmployee($req){
$employee = new Employee();
$employee->Load("id = ?",array($req->id));
if(empty($employee->id)){
return new IceResponse(IceResponse::ERROR, "Employee Not Found");
}
$archived = new ArchivedEmployee();
$archived->ref_id = $employee->id;
$archived->employee_id = $employee->employee_id;
$archived->first_name = $employee->first_name;
$archived->last_name = $employee->last_name;
$archived->gender = $employee->gender;
$archived->ssn_num = $employee->ssn_num;
$archived->nic_num = $employee->nic_num;
$archived->other_id = $employee->other_id;
$archived->work_email = $employee->work_email;
$archived->joined_date = $employee->joined_date;
$archived->confirmation_date = $employee->confirmation_date;
$archived->supervisor = $employee->supervisor;
$archived->department = $employee->department;
$archived->termination_date = $employee->termination_date;
$archived->notes = $employee->notes;
//$archived = BaseService::getInstance()->cleanUpAdoDB($archived);
$mapping = '{"nationality":["Nationality","id","name"],"employment_status":["EmploymentStatus","id","name"],"job_title":["JobTitle","id","name"],"pay_grade":["PayGrade","id","name"],"country":["Country","code","name"],"province":["Province","id","name"],"department":["CompanyStructure","id","title"],"supervisor":["Employee","id","first_name+last_name"]}';
$employeeEnriched = BaseService::getInstance()->getElement('Employee',$employee->id,$mapping,true);
$employeeEnriched = BaseService::getInstance()->cleanUpAdoDB($employeeEnriched);
$data = new stdClass();
$data->enrichedEmployee = $employeeEnriched;
$data->timesheets = $this->getEmployeeData($employee->id, new EmployeeTimeSheet());
$data->timesheetEntries = $this->getEmployeeData($employee->id, new EmployeeTimeEntry());
$data->attendance = $this->getEmployeeData($employee->id, new Attendance());
$data->documents = $this->getEmployeeData($employee->id, new EmployeeDocument());
if(class_exists('EmployeeTrainingSession')){
$data->trainingSessions = $this->getEmployeeData($employee->id, new EmployeeTrainingSession());
}
$data->travelRecords = $this->getEmployeeData($employee->id, new EmployeeTravelRecord());
$data->qualificationSkills = $this->getEmployeeData($employee->id, new EmployeeSkill());
$data->qualificationEducation = $this->getEmployeeData($employee->id, new EmployeeEducation());
$data->qualificationCertifications = $this->getEmployeeData($employee->id, new EmployeeCertification());
$data->qualificationLanguages = $this->getEmployeeData($employee->id, new EmployeeLanguage());
$data->salary = $this->getEmployeeData($employee->id, new EmployeeSalary());
$data->dependants = $this->getEmployeeData($employee->id, new EmployeeDependent());
$data->emergencyContacts = $this->getEmployeeData($employee->id, new EmergencyContact());
$data->projects = $this->getEmployeeData($employee->id, new EmployeeProject());
$data->leaves = $this->getEmployeeData($employee->id, new EmployeeLeave());
$data->leaveDays = $this->getEmployeeData($employee->id, new EmployeeLeaveDay());
$archived->data = json_encode($data, JSON_PRETTY_PRINT);
$ok = $archived->Save();
if(!$ok){
return new IceResponse(IceResponse::ERROR, "Error occured while archiving employee");
}
$ok = $employee->Delete();
if(!$ok){
return new IceResponse(IceResponse::ERROR, "Error occured while deleting employee");
}
return new IceResponse(IceResponse::SUCCESS, $archived);
}
public function downloadArchivedEmployee($req){
if($this->baseService->currentUser->user_level != 'Admin'){
echo "Error: Permission denied";
exit();
}
$employee = new ArchivedEmployee();
$employee->Load("id = ?",array($req->id));
if(empty($employee->id)){
return new IceResponse(IceResponse::ERROR, "Employee Not Found");
}
$employee->data = json_decode($employee->data);
$employee = $this->baseService->cleanUpAdoDB($employee);
$str = json_encode($employee, JSON_PRETTY_PRINT);
$filename = uniqid();
$file = fopen("/tmp/".$filename,"w");
fwrite($file,$str);
fclose($file);
$downloadFileName = "employee_".$employee->id."_".str_replace(" ", "_", $employee->first_name)."_".str_replace(" ", "_", $employee->last_name).".txt";
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Description: File Transfer");
header("Content-Type: image/jpg");
header('Content-Disposition: attachment; filename="'.$downloadFileName.'"');
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize("/tmp/".$filename));
readfile("/tmp/".$filename);
exit();
}
private function getEmployeeData($id, $obj){
$data = array();
$objs = $obj->Find("employee = ?",array($id));
foreach($objs as $entry){
$data[] = BaseService::getInstance()->cleanUpAdoDB($entry);
}
return $data;
}
}

View File

@@ -10,6 +10,18 @@ if (!class_exists('EmployeesAdminManager')) {
}
public function setupRestEndPoints(){
\NoahBuscher\Macaw\Macaw::get(REST_API_PATH.'employee/(:any)', function($pathParams) {
$empRestEndPoint = new EmployeeRestEndPoint();
$empRestEndPoint->process('get',$pathParams);
});
\NoahBuscher\Macaw\Macaw::get(REST_API_PATH.'employees', function() {
$empRestEndPoint = new EmployeesRestEndPoint();
$empRestEndPoint->process('get',NULL);
});
}
public function initializeDatabaseErrorMappings(){
$this->addDatabaseErrorMapping('CONSTRAINT `Fk_User_Employee` FOREIGN KEY',"Can not delete Employee, please delete the User for this employee first.");
$this->addDatabaseErrorMapping("Duplicate entry|for key 'employee'","A duplicate entry found");
@@ -40,47 +52,288 @@ if (!class_exists('EmployeesAdminManager')) {
if (!class_exists('Employee')) {
class Employee extends ICEHRM_Record {
var $oldObj = null;
var $oldObjOrig = null;
var $historyUpdateList = array();
var $historyFieldsToTrack = array(
"employee_id"=>"employee_id",
"first_name"=>"first_name",
"middle_name"=>"middle_name",
"last_name"=>"last_name",
"nationality"=>"nationality_Name",
"birthday"=>"birthday",
"gender"=>"gender",
"marital_status"=>"marital_status",
"ssn_num"=>"ssn_num",
"nic_num"=>"nic_num",
"other_id"=>"other_id",
"employment_status"=>"employment_status_Name",
"job_title"=>"job_title_Name",
"pay_grade"=>"pay_grade_Name",
"work_station_id"=>"work_station_id",
"address1"=>"address1",
"address2"=>"address2",
"city"=>"city_Name",
"country"=>"country_Name",
"province"=>"province_Name",
"postal_code"=>"postal_code",
"home_phone"=>"home_phone",
"mobile_phone"=>"mobile_phone",
"work_phone"=>"work_phone",
"work_email"=>"work_email",
"private_email"=>"private_email",
"joined_date"=>"joined_date",
"confirmation_date"=>"confirmation_date",
"supervisor"=>"supervisor_Name",
"indirect_supervisors"=>"indirect_supervisors",
"department"=>"department_Name"
);
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getManagerAccess(){
return array("get","element","save");
}
public function getUserAccess(){
return array("get");
}
public function getUserOnlyMeAccess(){
return array("element","save");
}
public function getUserOnlyMeAccessField(){
return "id";
}
private function initHistory($obj){
$oldObjOrig = new Employee();
$oldObjOrig->Load("id = ?",array($obj->id));
$this->oldObjOrig = $oldObjOrig;
$mapping = '{"nationality":["Nationality","id","name"],"employment_status":["EmploymentStatus","id","name"],"job_title":["JobTitle","id","name"],"pay_grade":["PayGrade","id","name"],"country":["Country","code","name"],"province":["Province","id","name"],"department":["CompanyStructure","id","title"],"supervisor":["Employee","id","first_name+last_name"]}';
$this->oldObj = BaseService::getInstance()->getElement('Employee',$obj->id,$mapping,true);
}
private function saveHistory($obj){
$oldObj = $this->oldObj;
$oldObjOrig = $this->oldObjOrig;
$mapping = '{"nationality":["Nationality","id","name"],"employment_status":["EmploymentStatus","id","name"],"job_title":["JobTitle","id","name"],"pay_grade":["PayGrade","id","name"],"country":["Country","code","name"],"province":["Province","id","name"],"department":["CompanyStructure","id","title"],"supervisor":["Employee","id","first_name+last_name"]}';
$objEnriched = BaseService::getInstance()->getElement('Employee',$obj->id,$mapping,true);
foreach($this->historyFieldsToTrack as $k => $v){
if(empty($oldObjOrig->$k) && $obj->$k = '[]'){
continue;
}
if(empty($obj->$k) && $oldObjOrig->$k = '0000-00-00'){
continue;
}
if($oldObjOrig->$k != $obj->$k){
$enrichNewVal = '';
$enrichOldVal = '';
if($k == 'indirect_supervisors'){
if(!empty($obj->$k) && $obj->$k != '[]'){
$newIndeirectSupervisorIds = json_decode($obj->$k);
foreach($newIndeirectSupervisorIds as $id){
$item = BaseService::getInstance()->getItemFromCache("Employee", $id);
if($enrichNewVal != ""){
$enrichNewVal .= ", ";
}
$enrichNewVal .= $item->first_name." ".$item->last_name;
}
}
if(!empty($oldObjOrig->$k) && $oldObjOrig->$k != '[]'){
$oldIndeirectSupervisorIds = json_decode($oldObjOrig->$k);
foreach($oldIndeirectSupervisorIds as $id){
$item = BaseService::getInstance()->getItemFromCache("Employee", $id);
if($enrichOldVal != ""){
$enrichOldVal .= ", ";
}
$enrichOldVal .= $item->first_name." ".$item->last_name;
}
}
}else{
$enrichOldVal = $oldObj->$v;
$enrichNewVal = $objEnriched->$v;
}
$this->historyUpdateList[] = array($obj->id,$k,$enrichOldVal,$enrichNewVal);
}
}
while(count($this->historyUpdateList)){
$ele = array_pop($this->historyUpdateList);
BaseService::getInstance()->addHistoryItem("Employee","Employee",$ele[0],$ele[1],$ele[2],$ele[3]);
}
}
public function executePreSaveActions($obj){
if(empty($obj->status)){
$obj->status = 'Active';
}
return new IceResponse(IceResponse::SUCCESS,$obj);
}
public function executePreUpdateActions($obj){
$this->initHistory($obj);
return new IceResponse(IceResponse::SUCCESS,$obj);
}
public function executePostUpdateActions($obj){
$this->saveHistory($obj);
}
public function postProcessGetData($obj){
$obj = FileService::getInstance()->updateSmallProfileImage($obj);
return $obj;
}
public function getVirtualFields(){
return array(
"image"
);
}
public function getActiveEmployees(){
$employee = new Employee();
$list = $employee->Find("status = ?",array('Active'));
return $list;
}
public function getActiveSubordinateEmployees(){
$employee = new Employee();
if(BaseService::getInstance()->currentUser->user_level != 'Admin'){
$cemp = BaseService::getInstance()->getCurrentProfileId();
$list = $employee->Find("status = ? and supervisor = ?",array('Active', $cemp));
}else{
$list = $employee->Find("status = ?",array('Active'));
}
return $list;
}
public static function cleanEmployeeData($obj){
unset($obj->historyFieldsToTrack);
unset($obj->historyUpdateList);
unset($obj->oldObjOrig);
unset($obj->oldObj);
unset($obj->oldObj);
return $obj;
}
var $_table = 'Employees';
}
}
if (!class_exists('ArchivedEmployee')) {
class ArchivedEmployee extends ICEHRM_Record {
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getManagerAccess(){
return array("get","element","save");
}
public function getUserAccess(){
return array("get");
}
public function getUserOnlyMeAccess(){
return array("element","save");
}
public function getUserOnlyMeAccessField(){
return "id";
}
var $_table = 'ArchivedEmployees';
}
}
if (!class_exists('EmploymentStatus')) {
class EmploymentStatus extends ICEHRM_Record {
var $_table = 'EmploymentStatus';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getManagerAccess(){
return array("get","element","save");
}
public function getUserAccess(){
return array();
}
}
}
if (!class_exists('EmployeeRestEndPoint')) {
class EmployeeRestEndPoint extends RestEndPoint{
public function get($parameter){
if(empty($parameter)){
return new IceResponse(IceResponse::ERROR, "Employee ID not provided");
}
$accessTokenValidation = $this->validateAccessToken();
if($accessTokenValidation->getStatus() == IceResponse::ERROR){
return $accessTokenValidation;
}
$mapping = '{"nationality":["Nationality","id","name"],"ethnicity":["Ethnicity","id","name"],"immigration_status":["ImmigrationStatus","id","name"],"employment_status":["EmploymentStatus","id","name"],"job_title":["JobTitle","id","name"],"pay_grade":["PayGrade","id","name"],"country":["Country","code","name"],"province":["Province","id","name"],"department":["CompanyStructure","id","title"],"supervisor":["Employee","id","first_name+last_name"]}';
$employeeResp = BaseService::getInstance()->getElement('Employee',$parameter,$mapping,true);
if($employeeResp->getStatus() == IceResponse::SUCCESS){
$emp = $employeeResp->getObject();
$emp = Employee::cleanEmployeeData($emp);
return new IceResponse(IceResponse::SUCCESS,$emp);
}
return $employeeResp;
}
}
}
if (!class_exists('EmployeesRestEndPoint')) {
class EmployeesRestEndPoint extends RestEndPoint{
public function get($parameter){
$accessTokenValidation = $this->validateAccessToken();
if($accessTokenValidation->getStatus() == IceResponse::ERROR){
return $accessTokenValidation;
}
$emp = new Employee();
$emps = $emp->Find("1=1");
$newEmps = array();
foreach($emps as $emp){
$newEmps[] = Employee::cleanEmployeeData($emp);
}
return new IceResponse(IceResponse::SUCCESS, $newEmps);
}
}
}