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

@@ -34,6 +34,12 @@ if (!class_exists('AttendanceAdminManager')) {
UIManager::getInstance()->addQuickAccessMenuItem("Clocked In Employees","fa-clock-o",CLIENT_BASE_URL."?g=admin&n=attendance&m=admin_Employees#tabAttendanceStatus",array("Admin","Manager"));
}
public function initCalculationHooks(){
$this->addCalculationHook('AttendanceUtil_getTimeWorkedHours','Total Hours from Attendance','AttendanceUtil','getTimeWorkedHours');
$this->addCalculationHook('AttendanceUtil_getRegularWorkedHours','Total Regular Hours from Attendance','AttendanceUtil','getRegularWorkedHours');
$this->addCalculationHook('AttendanceUtil_getOverTimeWorkedHours','Total Overtime Hours from Attendance','AttendanceUtil','getOverTimeWorkedHours');
}
}
}
@@ -213,6 +219,39 @@ if (!class_exists('AttendanceStatus')) {
}
}
if (!class_exists('AttendanceUtil')) {
class AttendanceUtil{
public function getAttendanceSummary($employeeId, $startDate, $endDate){
$startTime = $startDate." 00:00:00";
$endTime = $endDate." 23:59:59";
$attendance = new Attendance();
$atts = $attendance->Find("employee = ? and in_time >= ? and out_time <= ?",array($employeeId, $startTime, $endTime));
$atCalClassName = SettingsManager::getInstance()->getSetting('Attendance: Overtime Calculation Class');
$atCal = new $atCalClassName();
$atSum = $atCal->getDataSeconds($atts, $startDate, true);
return $atSum;
}
public function getTimeWorkedHours($employeeId, $startDate, $endDate){
$atSum = $this->getAttendanceSummary($employeeId, $startDate, $endDate);
return round(($atSum['t']/60)/60,2);
}
public function getRegularWorkedHours($employeeId, $startDate, $endDate){
$atSum = $this->getAttendanceSummary($employeeId, $startDate, $endDate);
return round(($atSum['r']/60)/60,2);
}
public function getOverTimeWorkedHours($employeeId, $startDate, $endDate){
$atSum = $this->getAttendanceSummary($employeeId, $startDate, $endDate);
return round(($atSum['o']/60)/60,2);
}
}
}
if (!class_exists('BasicOvertimeCalculator')) {
@@ -305,6 +344,18 @@ if (!class_exists('BasicOvertimeCalculator')) {
}
public function getDataSeconds($atts, $actualStartDate, $aggregate = false){
$atSummary = $this->createAttendanceSummary($atts);
$overtime = $this->calculateOvertime($this->removeAdditionalDays($atSummary, $actualStartDate));
if($aggregate){
$overtime = $this->aggregateData($overtime);
return $overtime;
}else{
return $overtime;
}
}
public function convertToHours($overtime){

View File

@@ -0,0 +1,156 @@
<?php
if (!class_exists('ChartsActionManager')) {
class ChartsActionManager extends SubActionManager{
public function getTimeUtilization($req){
if(empty($req->start)){
$req->start = date("Y-m-01");
}
if(empty($req->end)){
$req->end = date("Y-m-t",strtotime($req->start));
}
//Find Time Entries
$employeeTimeEntry = new EmployeeTimeEntry();
if(empty($req->employee)){
$timeEntryList = $employeeTimeEntry->Find("date(date_start) >= ? and date(date_end) <= ?",array($req->start, $req->end));
}else{
$timeEntryList = $employeeTimeEntry->Find("employee = ? and date(date_start) >= ? and date(date_end) <= ?",array($req->employee, $req->start, $req->end));
}
$seconds = 0;
$graphTimeArray = array();
foreach($timeEntryList as $entry){
$seconds = (strtotime($entry->date_end) - strtotime($entry->date_start));
$key = date("Y-m-d",strtotime($entry->date_end));
if(isset($graphTimeArray[$key])){
$graphTimeArray[$key] += $seconds;
}else{
$graphTimeArray[$key] = $seconds;
}
}
//$minutes = (int)($seconds/60);
//Find Attendance Entries
$attendance = new Attendance();
if(empty($req->employee)){
$atteandanceList = $attendance->Find("date(in_time) >= ? and date(out_time) <= ? and in_time < out_time",array($req->start, $req->end));
}else{
$atteandanceList = $attendance->Find("employee = ? and date(in_time) >= ? and date(out_time) <= ? and in_time < out_time",array($req->employee, $req->start, $req->end));
}
$seconds = 0;
$graphAttendanceArray = array();
foreach($atteandanceList as $entry){
$seconds = (strtotime($entry->out_time) - strtotime($entry->in_time));
$key = date("Y-m-d",strtotime($entry->in_time));
if(isset($graphAttendanceArray[$key])){
$graphAttendanceArray[$key] += $seconds;
}else{
$graphAttendanceArray[$key] = $seconds;
}
}
$data = array();
$data[] = array("key"=>"Hours in Attendance", "values"=>array());
$data[] = array("key"=>"Hours Worked", "values"=>array());
//Iterate date range
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod(new DateTime($req->start), $interval, new DateTime($req->end));
foreach ( $period as $dt ){
$key = $dt->format("Y-m-d");
if(isset($graphAttendanceArray[$key])){
$data[0]['values'][] = array("x"=>$key, "y"=>round(($graphAttendanceArray[$key]/3600),2));
}else{
$data[0]['values'][] = array("x"=>$key, "y"=>0);
}
if(isset($graphTimeArray[$key])){
$data[1]['values'][] = array("x"=>$key, "y"=>round(($graphTimeArray[$key]/3600),2));
}else{
$data[1]['values'][] = array("x"=>$key, "y"=>0);
}
}
/*
//Test data
for($i = 1; $i<31; $i++){
$data[0]['values'][] = array("x"=>$i, "y"=>rand(2,9));
$data[1]['values'][] = array("x"=>$i, "y"=>rand(2,8));
}
*/
return new IceResponse(IceResponse::SUCCESS,$data);
}
public function getAttendance($req){
if(empty($req->start)){
$req->start = date("Y-m-01");
}
if(empty($req->end)){
$req->end = date("Y-m-t",strtotime($req->start));
}
//Find Attendance Entries
$attendance = new Attendance();
if(empty($req->employee)){
$atteandanceList = $attendance->Find("date(in_time) >= ? and date(out_time) <= ? and in_time < out_time",array($req->start, $req->end));
}else{
$atteandanceList = $attendance->Find("employee = ? and date(in_time) >= ? and date(out_time) <= ? and in_time < out_time",array($req->employee, $req->start, $req->end));
}
$seconds = 0;
$graphAttendanceArray = array();
foreach($atteandanceList as $entry){
$seconds = (strtotime($entry->out_time) - strtotime($entry->in_time));
$key = date("Y-m-d",strtotime($entry->in_time));
if(isset($graphAttendanceArray[$key])){
$graphAttendanceArray[$key] += $seconds;
}else{
$graphAttendanceArray[$key] = $seconds;
}
}
$data[0] = array();
$data[0] = array("key"=>"Attendance", "values"=>array());
//Iterate date range
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod(new DateTime($req->start), $interval, new DateTime($req->end));
foreach ( $period as $dt ){
$key = $dt->format("Y-m-d");
if(isset($graphAttendanceArray[$key])){
$data[0]['values'][] = array("x"=>$key, "y"=>round(($graphAttendanceArray[$key]/3600),2));
}else{
$data[0]['values'][] = array("x"=>$key, "y"=>0);
}
}
return new IceResponse(IceResponse::SUCCESS,$data);
}
}
}

View File

@@ -0,0 +1,22 @@
<?php
if (!class_exists('ChartsAdminManager')) {
class ChartsAdminManager extends AbstractModuleManager{
public function initializeUserClasses(){
}
public function initializeFieldMappings(){
}
public function initializeDatabaseErrorMappings(){
}
public function setupModuleClassDefinitions(){
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
$moduleName = 'company_structure';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
?>
<link href="<?=BASE_URL.'js/nvd3/src/nv.d3.css?v='.$jsVersion?>" rel="stylesheet" type="text/css">
<script src="<?=BASE_URL.'js/nvd3/lib/d3.v3.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/nv.d3.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/tooltip.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/utils.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/models/legend.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/models/axis.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/models/multiBar.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/models/discreteBar.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/src/models/discreteBarChart.js?v='.$jsVersion?>"></script>
<script src="<?=BASE_URL.'js/nvd3/stream_layers.js?v='.$jsVersion?>"></script>
<style type="text/css">
svg .tooltip { opacity: 1; }
</style>
<div class="span9">
<ul class="nav nav-tabs" id="modTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">
<li class="active"><a id="tabAttendanceGraph" href="#tabPageAttendanceGraph">Attendance Graph</a></li>
<li><a id="tabTimeUtilizationGraph" href="#tabPageTimeUtilizationGraph">Hours in Office vs Hours Worked Graph</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active reviewBlock with-3d-shadow with-transitions" id="tabPageAttendanceGraph" style="height: 500px;position: relative;">
<svg></svg>
</div>
<div class="tab-pane reviewBlock with-3d-shadow with-transitions" id="tabPageTimeUtilizationGraph" style="height: 500px;position: relative;">
<svg></svg>
</div>
</div>
</div>
<script>
var modJsList = new Array();
modJsList['tabAttendanceGraph'] = new AttendanceGraphAdapter('AttendanceGraph');
modJsList['tabAttendanceGraph'].setShowAddNew(false);
modJsList['tabTimeUtilizationGraph'] = new TimeUtilizationGraphAdapter('TimeUtilizationGraph');
modJsList['tabTimeUtilizationGraph'].setShowAddNew(false);
var modJs = modJsList['tabAttendanceGraph'];
</script>
<?php include APP_BASE_PATH.'footer.php';?>

284
ext/admin/charts/lib.js Normal file
View File

@@ -0,0 +1,284 @@
/**
* Author: Thilina Hasantha
*/
function BaseGraphAdapter(endPoint) {
this.initAdapter(endPoint);
}
BaseGraphAdapter.inherits(AdapterBase);
BaseGraphAdapter.method('getDataMapping', function() {
return [];
});
BaseGraphAdapter.method('getHeaders', function() {
return [];
});
BaseGraphAdapter.method('getFormFields', function() {
return [];
});
BaseGraphAdapter.method('createTable', function(elementId) {
});
/*
* TimeUtilizationGraphAdapter
*/
function AttendanceGraphAdapter(endPoint) {
this.initAdapter(endPoint);
}
AttendanceGraphAdapter.inherits(BaseGraphAdapter);
AttendanceGraphAdapter.method('getFormFields', function() {
return [];
});
AttendanceGraphAdapter.method('getFilters', function() {
return [
[ "employee", {"label":"Employee","type":"select2","allow-null":true,"null-label":"All Employees","remote-source":["Employee","id","first_name+last_name"]}],
[ "start", {"label":"Start Date","type":"date","validation":""}],
[ "end", {"label":"End Date","type":"date","validation":""}]
];
});
AttendanceGraphAdapter.method('get', function() {
this.initFieldMasterData();
this.getTimeUtilization();
});
AttendanceGraphAdapter.method('doCustomFilterValidation', function(params) {
$("#"+this.table+"_filter_error").html("");
$("#"+this.table+"_filter_error").hide();
if(Date.parse(params.start).getTime() > Date.parse(params.end).getTime()){
$("#"+this.table+"_filter_error").html("End date should be a later date than start date");
$("#"+this.table+"_filter_error").show();
return false;
}
var dateDiff = (Date.parse(params.end).getTime() - Date.parse(params.start).getTime())/(1000*60*60*24);
if(dateDiff > 45 && (params['employee'] == undefined || params['employee'] == null || params['employee'] == "NULL")){
$("#"+this.table+"_filter_error").html("Differance between start and end dates should not be more than 45 days, when creating chart for all employees");
$("#"+this.table+"_filter_error").show();
return false;
}else if(dateDiff > 90){
$("#"+this.table+"_filter_error").html("Differance between start and end dates should not be more than 90 days");
$("#"+this.table+"_filter_error").show();
return false;
}
return true;
});
AttendanceGraphAdapter.method('getTimeUtilization', function(object,callBackData) {
var that = this;
object = {};
if(this.filter != null && this.filter != undefined){
if(this.filter.employee != "NULL"){
object['employee'] = this.filter.employee;
}
object['start'] = this.filter.start;
object['end'] = this.filter.end;
}
var reqJson = JSON.stringify(object);
var callBackData = [];
callBackData['callBackData'] = [];
callBackData['callBackSuccess'] = 'getAttendanceSuccessCallBack';
callBackData['callBackFail'] = 'getAttendanceFailCallBack';
this.customAction('getAttendance','admin=charts',reqJson,callBackData);
});
AttendanceGraphAdapter.method('getAttendanceFailCallBack', function(callBackData) {
this.showMessage("Error Occured while getting data for chart", callBackData);
});
AttendanceGraphAdapter.method('getAttendanceSuccessCallBack', function(callBackData) {
var that = this;
var chart;
var filterHtml = that.getTableTopButtonHtml();
$("#tabPageAttendanceGraph svg").remove();
$("#tabPageAttendanceGraph div").remove();
$("#tabPageAttendanceGraph").html("");
$("#tabPageAttendanceGraph").html(filterHtml+"<svg></svg>");
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
.margin({bottom: 200})
.transitionDuration(0)
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
.rotateLabels(45) //Angle to rotate x-axis labels.
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
;
chart.yAxis
.tickFormat(d3.format(',.1f'));
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
chart.tooltip(function (key, x, y, e, graph) {
return '<p><strong>' + key + '</strong></p>' +
'<p>' + y + ' on ' + x + '</p>';
});
d3.select('#tabPageAttendanceGraph svg')
.datum(callBackData)
.call(chart);
return chart;
});
});
/*
* TimeUtilizationGraphAdapter
*/
function TimeUtilizationGraphAdapter(endPoint) {
this.initAdapter(endPoint);
}
TimeUtilizationGraphAdapter.inherits(BaseGraphAdapter);
TimeUtilizationGraphAdapter.method('getFormFields', function() {
return [];
});
TimeUtilizationGraphAdapter.method('getFilters', function() {
return [
[ "employee", {"label":"Employee","type":"select2","allow-null":true,"null-label":"All Employees","remote-source":["Employee","id","first_name+last_name"]}],
[ "start", {"label":"Start Date","type":"date","validation":""}],
[ "end", {"label":"End Date","type":"date","validation":""}]
];
});
TimeUtilizationGraphAdapter.method('get', function() {
this.initFieldMasterData();
this.getTimeUtilization();
});
TimeUtilizationGraphAdapter.method('doCustomFilterValidation', function(params) {
$("#"+this.table+"_filter_error").html("");
$("#"+this.table+"_filter_error").hide();
if(Date.parse(params.start).getTime() > Date.parse(params.end).getTime()){
$("#"+this.table+"_filter_error").html("End date should be a later date than start date");
$("#"+this.table+"_filter_error").show();
return false;
}
var dateDiff = (Date.parse(params.end).getTime() - Date.parse(params.start).getTime())/(1000*60*60*24);
if(dateDiff > 45 && (params['employee'] == undefined || params['employee'] == null || params['employee'] == "NULL")){
$("#"+this.table+"_filter_error").html("Differance between start and end dates should not be more than 45 days, when creating chart for all employees");
$("#"+this.table+"_filter_error").show();
return false;
}else if(dateDiff > 90){
$("#"+this.table+"_filter_error").html("Differance between start and end dates should not be more than 90 days");
$("#"+this.table+"_filter_error").show();
return false;
}
return true;
});
TimeUtilizationGraphAdapter.method('getTimeUtilization', function(object,callBackData) {
var that = this;
object = {};
if(this.filter != null && this.filter != undefined){
if(this.filter.employee != "NULL"){
object['employee'] = this.filter.employee;
}
object['start'] = this.filter.start;
object['end'] = this.filter.end;
}
var reqJson = JSON.stringify(object);
var callBackData = [];
callBackData['callBackData'] = [];
callBackData['callBackSuccess'] = 'getTimeUtilizationSuccessCallBack';
callBackData['callBackFail'] = 'getTimeUtilizationFailCallBack';
this.customAction('getTimeUtilization','admin=charts',reqJson,callBackData);
});
TimeUtilizationGraphAdapter.method('getTimeUtilizationFailCallBack', function(callBackData) {
this.showMessage("Error Occured while getting data for chart", callBackData);
});
TimeUtilizationGraphAdapter.method('getTimeUtilizationSuccessCallBack', function(callBackData) {
var that = this;
var chart;
var filterHtml = that.getTableTopButtonHtml();
$("#tabPageTimeUtilizationGraph svg").remove();
$("#tabPageTimeUtilizationGraph div").remove();
$("#tabPageTimeUtilizationGraph").html("");
$("#tabPageTimeUtilizationGraph").html(filterHtml+"<svg></svg>");
nv.addGraph(function() {
var chart = nv.models.multiBarChart()
.margin({bottom: 200})
.transitionDuration(0)
.reduceXTicks(true) //If 'false', every single x-axis tick label will be rendered.
.rotateLabels(45) //Angle to rotate x-axis labels.
.showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.1) //Distance between each group of bars.
;
chart.yAxis
.tickFormat(d3.format(',.1f'));
d3.select('#tabPageTimeUtilizationGraph svg')
.datum(callBackData)
.call(chart);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
chart.tooltip(function (key, x, y, e, graph) {
return '<p><strong>' + key + '</strong></p>' +
'<p>' + y + ' on ' + x + '</p>';
});
return chart;
});
});

View File

@@ -0,0 +1,11 @@
{
"label":"Performance Charts",
"menu":"Employees",
"order":"93",
"icon":"fa-bar-chart-o",
"user_levels":["Admin","Manager"],
"permissions":
{
}
}

View File

@@ -56,6 +56,37 @@ if (!class_exists('CompanyStructure')) {
return new IceResponse(IceResponse::SUCCESS,"");
}
public static function getAllChildCompanyStructures($companyStructureId){
$structures = array();
$companyStructure = new CompanyStructure();
$companyStructure->Load("id = ?",array($companyStructureId));
if($companyStructure->id != $companyStructureId || empty($companyStructure->id)){
return new IceResponse(IceResponse::ERROR, array());
}
self::getChildCompanyStructures($companyStructure, $structures);
$structures[$companyStructure->id] = $companyStructure;
return new IceResponse(IceResponse::SUCCESS, array_values($structures));
}
private static function getChildCompanyStructures($companyStructure, &$structures){
$child = new CompanyStructure();
$children = $child->Find("parent = ?",array($companyStructure->id));
if(!empty($children)){
foreach($children as $c){
if(isset($structures[$c->id])){
continue;
}
$structures[$c->id] = $c;
self::getChildCompanyStructures($c, $structures);
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
ICEHRM END USER LICENSE AGREEMENT
NOTICE TO ALL USERS: BY PURCHASING THE MODULE, YOU (EITHER AN INDIVIDUAL OR A SINGLE ENTITY) CONSENT TO BE BOUND BY AND BECOME A PARTY TO THIS AGREEMENT.
All references to "Software" herein shall be deemed to include the software license with which you will be provided by Gamonoid Media Pvt Ltd, as part of the Software.
1. LICENSE GRANT. Subject to the payment of the applicable licence fees, and subject to the terms and conditions of this Agreement, ICEHRM hereby grants to you a non-exclusive, non-transferable right to use one copy of the specified version of the Software and the accompanying documentation (the "Documentation") for the term of this Agreement solely for your own internal business purposes. You may install one copy of the Software for production use.
.
2. USE. The Software is licensed as a single product; it may not be used on more than one ICEHRM Server at a time. The Software is "in use" on a Server when its installed on a Server. You shall not, nor permit any third party to copy (other than as expressly permitted herein). You shall not rent, lease or lend the Software to any other person, nor transfer or sub-licence your licence rights to any other person.
3. TERM. This Agreement is effective until terminated as set forth herein. This Agreement will terminate automatically if you fail to comply with any of the conditions, limitations or other requirements described herein. Upon any termination of this Agreement, you must immediately destroy all copies of the Software and the Documentation. You may terminate this Agreement at any point by destroying all copies of the Software and the Documentation.
4. SUPPORT. Gamonoid Media Pvt Ltd will provide you support according to the support agreement subscribed by the company.
5. OWNERSHIP RIGHTS. The Software is protected by copyright laws. ICEHRM and Gamonoid Media Pvt Ltd own and retain all right, title and interest in and to the Software, including all copyrights, patents, trademarks and other intellectual property rights therein. Your possession, installation, or use of the Software does not transfer to you any title to the intellectual property in the Software, and you will not acquire any rights to the Software except as expressly set forth in this Agreement.
6. LIMITED WARRANTY. You may not rent, lease, loan or resell the Software. You may not permit third parties to benefit from the use or functionality of the Software via a timesharing, service bureau or other arrangement, except to the extent such use is specified in the applicable list price or product packaging for the Software. You may not transfer any of the rights granted to you under this Agreement. You may not modify, or create derivative works based upon, the Software in whole or in part. You may not copy the Software or Documentation except as expressly permitted in Section 1 above. You may not remove any proprietary notices or labels on the Software. All rights not expressly set forth hereunder are reserved by ICEHRM. ICEHRM reserves the right to periodically conduct audits upon advance written notice to verify compliance with the terms of this Agreement.
7. WARRANTY and DISCLAIMER.
(i) Gamonoid Media Pvt Ltd. warrants that for 30 days from first download or installation the Software will perform substantially in accordance with the functionality described in the Documentation (http://blog.icehrm.com) when operated properly and in the manner specified in the Documentation.
(ii) You accept all responsibility for the selection of this Software to meet your requirements.
(iii) Gamonoid Media Pvt Ltd. does not warrant that the Software and/or the Documentation will be suitable for such requirements nor that any use will be uninterrupted and error free.
(iv) The warranty in (i) shall not apply if you (a) make or cause to be made any modifications to this Software, (b) use the Software in a manner for which it was not intended or (c) use the Software other than as permitted under this Agreement.
(vii) The warranties and conditions stated in this Agreement are in lieu of all other conditions, warranties or other terms concerning the supply or purported supply of, failure to supply or delay in supplying the Software or the Documentation which might but for this paragraph (vii) have effect between the ICEHRM and you or would otherwise be implied into or incorporated into this Agreement or any collateral contract, whether by statute, common law or otherwise, all of which are hereby excluded (including, without limitation, the implied conditions, warranties or other terms as to satisfactory quality, fitness for purpose or as to the use of reasonable skill and care).
8. LIMITATION of LIABILITY. Gamonoid Media Pvt Ltd. shall have no liability (whether in contract, tort, restitution or otherwise) for any of the following losses or damage (whether such losses or damage were foreseen, foreseeable, known or otherwise):
- Loss of revenue;
- Loss of actual or anticipated profits (including for loss of profits on contracts);
- Loss of the use of money;
- Loss of anticipated savings;
- Loss of business;
- Loss of opportunity;
- Loss of goodwill;
- Loss of reputation;
- Loss of, damage to or corruption of data;
or
Any indirect or consequential loss or damage howsoever caused (including, for the avoidance of doubt, where such loss or damage is of the type specified in paragraph (ii), (a) to (ii), (i).
The ICEHRM liability (whether in contract, tort, restitution or otherwise) arising out of or in connection with the supply of the Software shall in no circumstances exceed a sum equal to the amount equally paid by you for the Software.
The construction and interpretation of this Agreement shall be governed in accordance with the laws of Sri Lanka. The parties hereby submit to the jurisdiction of the courts of Sri Lanka save that ICEHRM as claimant shall be entitled to initiate proceedings in any court of competent jurisdiction.
This Agreement contains the entire understanding of the parties with respect to the subject matter hereof and supersedes all and any prior understandings, undertakings and promises between you and ICEHRM, whether oral or in writing, which have been given or may be implied from anything written or said in negotiations between us or our representatives prior to this Agreement and all prior agreements between the parties relating to the matters aforesaid shall cease to have effect as from the Effective Date.

View File

@@ -0,0 +1,7 @@
This module is licensed under IceHrm Commercial License, which can be found in LICENSE.txt.
You are allowed to make any modification required to these module, but only allowed to use
the module in one production server (even with modifications).
Installation
------------
Copy this module into <icehrm path>/admin/ directory

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);
}
}
}

View File

@@ -0,0 +1,248 @@
<div class="row">
<div class="col-xs-12 col-md-2">
<div class="row-fluid">
<div class="col-xs-12" style="text-align: center;">
<img id="profile_image__id_" src="" class="img-polaroid img-thumbnail" style="max-width: 140px;max-height: 140px;">
</div>
</div>
</div>
<div class="col-xs-12 col-md-10">
<div class="row-fluid">
<div class="col-md-12"><h2 id="name"></h2></div>
</div>
<div class="row-fluid">
<div class="col-md-12">
<p>
<i class="fa fa-phone"></i> <span id="mobile_phone"></span>&nbsp;&nbsp;
<i class="fa fa-envelope"></i> <span id="work_email"></span>
</p>
</div>
</div>
<div class="row-fluid">
<div class="col-xs-12" style="font-size:18px;border-bottom: 1px solid #DDD;margin-bottom: 10px;padding-bottom: 10px;">
<button id="employeeProfileEditInfo" class="btn btn-small btn-success" onclick="modJs.edit(_id_);" style="margin-right:10px;"><i class="fa fa-edit"></i> Edit Info</button>
<button id="employeeUploadProfileImage" onclick="showUploadDialog('profile_image__id_','Upload Profile Image','profile_image',_id_,'profile_image__id_','src','url','image');return false;" class="btn btn-small btn-primary" type="button" style="margin-right:10px;"><i class="fa fa-upload"></i> Upload Profile Image</button>
<button id="employeeDeleteProfileImage" onclick="modJs.deleteProfileImage(_id_);return false;" class="btn btn-small btn-warning" type="button" style="margin-right:10px;"><i class="fa fa-times"></i> Delete Profile Image</button>
</div>
</div>
<div class="row-fluid" style="border-top: 1px;">
<div class="col-xs-6 col-md-4" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;font-size:13px;">#_label_employee_id_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="employee_id"></label>
</div>
<div class="col-xs-6 col-md-4" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_nic_num_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="nic_num"></label>
</div>
<div class="col-xs-6 col-md-4" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_ssn_num_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="ssn_num"></label>
</div>
</div>
</div>
</div>
<ul class="nav nav-tabs" id="subModTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">
<li class="active"><a id="tabBasic" href="#tabPageBasic">Basic Information</a></li>
<li class=""><a id="tabQualifications" href="#tabPageQualifications">Qualifications</a></li>
<li class=""><a id="tabDocuments" href="#tabPageDocuments">Documents</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tabPageBasic" style="border:1px solid #DDD;">
<div class="row" style="margin-left:10px;margin-top:20px;">
<div class="panel panel-default" style="width:97.5%;">
<div class="panel-heading"><h4>Personal Information</h4></div>
<div class="panel-body">
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_driving_license_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="driving_license"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_other_id_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="other_id"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_birthday_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="birthday"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_gender_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="gender"></label>
</div>
</div>
<hr/>
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_nationality_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="nationality_Name"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_marital_status_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="marital_status"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_joined_date_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="joined_date"></label>
</div>
</div>
</div>
</div>
</div>
<div class="row" style="margin-left:10px;margin-top:20px;">
<div class="panel panel-default" style="width:97.5%;">
<div class="panel-heading"><h4>Contact Information</h4></div>
<div class="panel-body">
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_address1_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="address1"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_address2_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="address2"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_city_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="city"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_country_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="country_Name"></label>
</div>
</div>
<hr/>
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_postal_code_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="postal_code"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_home_phone_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="home_phone"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_work_phone_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="work_phone"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_private_email_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="private_email"></label>
</div>
</div>
</div>
</div>
</div>
<div class="row" style="margin-left:10px;margin-top:20px;">
<div class="panel panel-default" style="width:97.5%;">
<div class="panel-heading"><h4>Job Details</h4></div>
<div class="panel-body">
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_job_title_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="job_title_Name"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_employment_status_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="employment_status_Name"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_supervisor_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="supervisor_Name"></label>
</div>
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">Direct Reports</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="subordinates"></label>
</div>
</div>
<hr/>
<div class="row-fluid">
<div class="col-xs-6 col-md-3" style="font-size:16px;">
<label class="control-label col-xs-12" style="font-size:13px;">#_label_department_#</label>
<label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;" id="department_Name"></label>
</div>
</div>
</div>
</div>
</div>
<div class="modal" id="adminUsersModel" tabindex="-1" role="dialog" aria-labelledby="messageModelLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><li class="fa fa-times"/></button>
<h3 style="font-size: 17px;">Change User Password</h3>
</div>
<div class="modal-body">
<form id="adminUsersChangePwd">
<div class="control-group">
<div class="controls">
<span class="label label-warning" id="adminUsersChangePwd_error" style="display:none;"></span>
</div>
</div>
<div class="control-group" id="field_newpwd">
<label class="control-label" for="newpwd">New Password</label>
<div class="controls">
<input class="" type="password" id="newpwd" name="newpwd" value="" class="form-control"/>
<span class="help-inline" id="help_newpwd"></span>
</div>
</div>
<div class="control-group" id="field_conpwd">
<label class="control-label" for="conpwd">Confirm Password</label>
<div class="controls">
<input class="" type="password" id="conpwd" name="conpwd" value="" class="form-control"/>
<span class="help-inline" id="help_conpwd"></span>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="modJs.changePasswordConfirm();">Change Password</button>
<button class="btn" onclick="modJs.closeChangePassword();">Not Now</button>
</div>
</div>
</div>
</div>
</div><!-- End tabPageBasic -->
<div class="tab-pane" id="tabPageQualifications" style="border:1px solid #DDD;">
<div class="row" style="margin-top:20px;">
<div class="col-md-3">
<div id="EmployeeSkillSubTab" class="" data-content="List" style="padding-left:5px;">
</div>
</div>
<div class="col-md-3">
<div id="EmployeeEducationSubTab" class="" data-content="List" style="padding-left:5px;">
</div>
</div>
<div class="col-md-3">
<div id="EmployeeCertificationSubTab" class="" data-content="List" style="padding-left:5px;">
</div>
</div>
<div class="col-md-3">
<div id="EmployeeLanguageSubTab" class="" data-content="List" style="padding-left:5px;">
</div>
</div>
</div><!-- End tabPageQualifications -->
</div>
<div class="tab-pane" id="tabPageDocuments" style="border:1px solid #DDD;">
<div class="row" style="margin-top:20px;">
<div class="col-md-12">
<div id="EmployeeDocumentSubTab" class="" data-content="List" style="padding-left:5px;">
</div>
</div>
</div><!-- End tabPageQualifications -->
</div>
</div><!-- End tab-content -->

View File

@@ -0,0 +1,108 @@
ALTER TABLE Employees ADD COLUMN `status` enum('Active','Terminated') default 'Active';
create table `ArchivedEmployees` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`ref_id` bigint(20) NOT NULL,
`employee_id` varchar(50) default null,
`first_name` varchar(100) default '' not null,
`last_name` varchar(100) default '' not null,
`gender` enum('Male','Female') default NULL,
`ssn_num` varchar(100) default '',
`nic_num` varchar(100) default '',
`other_id` varchar(100) default '',
`work_email` varchar(100) default null,
`joined_date` DATETIME default '0000-00-00 00:00:00',
`confirmation_date` DATETIME default '0000-00-00 00:00:00',
`supervisor` bigint(20) default null,
`department` bigint(20) default null,
`termination_date` DATETIME default '0000-00-00 00:00:00',
`notes` text default null,
`data` longtext default null,
primary key (`id`)
) engine=innodb default charset=utf8;
create table `FieldNameMappings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`textOrig` varchar(200) default null,
`textMapped` varchar(200) default null,
`display` enum('Form','Table and Form','Hidden') default 'Form',
`created` DATETIME default '0000-00-00 00:00:00',
`updated` DATETIME default '0000-00-00 00:00:00',
primary key (`id`)
) engine=innodb default charset=utf8;
INSERT INTO `FieldNameMappings` (`type`, `name`, `textOrig`, `textMapped`, `display`) VALUES
('Employee', 'employee_id', 'Employee Number', 'Employee Number', 'Table and Form'),
('Employee', 'first_name', 'First Name', 'First Name', 'Table and Form'),
('Employee', 'middle_name', 'Middle Name', 'Middle Name', 'Form'),
('Employee', 'last_name', 'Last Name', 'Last Name', 'Table and Form'),
('Employee', 'nationality', 'Nationality', 'Nationality', 'Form'),
('Employee', 'birthday', 'Date of Birth', 'Date of Birth', 'Form'),
('Employee', 'gender', 'Gender', 'Gender', 'Form'),
('Employee', 'marital_status', 'Marital Status', 'Marital Status', 'Form'),
('Employee', 'ssn_num', 'SSN/NRIC', 'SSN/NRIC', 'Form'),
('Employee', 'nic_num', 'NIC', 'NIC', 'Form'),
('Employee', 'other_id', 'Other ID', 'Other ID', 'Form'),
('Employee', 'driving_license', 'Driving License No', 'Driving License No', 'Form'),
('Employee', 'employment_status', 'Employment Status', 'Employment Status', 'Form'),
('Employee', 'job_title', 'Job Title', 'Job Title', 'Form'),
('Employee', 'pay_grade', 'Pay Grade', 'Pay Grade', 'Form'),
('Employee', 'work_station_id', 'Work Station Id', 'Work Station Id', 'Form'),
('Employee', 'address1', 'Address Line 1', 'Address Line 1', 'Form'),
('Employee', 'address2', 'Address Line 2', 'Address Line 2', 'Form'),
('Employee', 'city', 'City', 'City', 'Form'),
('Employee', 'country', 'Country', 'Country', 'Form'),
('Employee', 'province', 'Province', 'Province', 'Form'),
('Employee', 'postal_code', 'Postal/Zip Code', 'Postal/Zip Code', 'Form'),
('Employee', 'home_phone', 'Home Phone', 'Home Phone', 'Form'),
('Employee', 'mobile_phone', 'Mobile Phone', 'Mobile Phone', 'Table and Form'),
('Employee', 'work_phone', 'Work Phone', 'Work Phone', 'Form'),
('Employee', 'work_email', 'Work Email', 'Work Email', 'Form'),
('Employee', 'private_email', 'Private Email', 'Private Email', 'Form'),
('Employee', 'joined_date', 'Joined Date', 'Joined Date', 'Form'),
('Employee', 'confirmation_date', 'Confirmation Date', 'Confirmation Date', 'Form'),
('Employee', 'termination_date', 'Termination Date', 'Termination Date', 'Form'),
('Employee', 'supervisor', 'Supervisor', 'Supervisor', 'Table and Form'),
('Employee', 'department', 'Department', 'Department', 'Table and Form'),
('Employee', 'notes', 'Notes', 'Notes', 'Form');
create table `CustomFields` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`type` varchar(20) NOT NULL,
`name` varchar(20) NOT NULL,
`data` text default null,
`display` enum('Form','Table and Form','Hidden') default 'Form',
`created` DATETIME default '0000-00-00 00:00:00',
`updated` DATETIME default '0000-00-00 00:00:00',
primary key (`id`)
) engine=innodb default charset=utf8;
INSERT INTO `CustomFields` (`type`, `name`, `data`,`display`) VALUES
('Employee', 'custom1', '', 'Hidden'),
('Employee', 'custom2', '', 'Hidden'),
('Employee', 'custom3', '', 'Hidden'),
('Employee', 'custom4', '', 'Hidden'),
('Employee', 'custom5', '', 'Hidden'),
('Employee', 'custom6', '', 'Hidden'),
('Employee', 'custom7', '', 'Hidden'),
('Employee', 'custom8', '', 'Hidden'),
('Employee', 'custom9', '', 'Hidden'),
('Employee', 'custom10', '', 'Hidden');
Alter table `Employees` MODIFY COLUMN `middle_name` varchar(100) default null;
Alter table `Employees` MODIFY COLUMN `last_name` varchar(100) default null;
Alter table `Employees` MODIFY COLUMN `ssn_num` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `nic_num` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `other_id` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `driving_license` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `work_station_id` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `address1` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `address2` varchar(100) default NULL;
Alter table `Employees` MODIFY COLUMN `city` varchar(150) default NULL;

View File

@@ -4,10 +4,41 @@ $moduleName = 'employees';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
$fieldNameMap = BaseService::getInstance()->getFieldNameMappings("Employee");
$customFields = BaseService::getInstance()->getCustomFields("Employee");
?><div class="span9">
<ul class="nav nav-tabs" id="modTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">
<li class="active"><a id="tabEmployee" href="#tabPageEmployee">Employees</a></li>
<?php if($user->user_level != "Admin"){
?>
<li class="active"><a id="tabEmployee" href="#tabPageEmployee">Employees (Direct Reports)</a></li>
<?php }else{ ?>
<li class="active"><a id="tabEmployee" href="#tabPageEmployee">Employees</a></li>
<?php }?>
<?php if($user->user_level == "Admin"){
?>
<li><a id="tabEmployeeSkill" href="#tabPageEmployeeSkill">Skills</a></li>
<li><a id="tabEmployeeEducation" href="#tabPageEmployeeEducation">Education</a></li>
<li><a id="tabEmployeeCertification" href="#tabPageEmployeeCertification">Certifications</a></li>
<li><a id="tabEmployeeLanguage" href="#tabPageEmployeeLanguage">Languages</a></li>
<li><a id="tabEmployeeDependent" href="#tabPageEmployeeDependent">Dependents</a></li>
<li><a id="tabEmergencyContact" href="#tabPageEmergencyContact">Emergency Contacts</a></li>
<?php if (!class_exists('DocumentsAdminManager')) {?>
<li><a id="tabEmployeeDocument" href="#tabPageEmployeeDocument">Documents</a></li>
<?php } ?>
<?php }?>
<?php if($user->user_level == "Admin"){
?>
<li class="dropdown">
<a href="#" id="terminatedEmployeeMenu" class="dropdown-toggle" data-toggle="dropdown" aria-controls="terminatedEmployeeMenu-contents">Suspended Employees <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu" aria-labelledby="terminatedEmployeeMenu" id="terminatedEmployeeMenu-contents">
<li><a id="tabTerminatedEmployee" href="#tabPageTerminatedEmployee">Temporarily Suspended Employees</a></li>
<li><a id="tabArchivedEmployee" href="#tabPageArchivedEmployee">Terminated Employee Data</a></li>
</ul>
</li>
<?php }?>
</ul>
<div class="tab-content">
@@ -19,16 +50,161 @@ include APP_BASE_PATH.'modulejslibs.inc.php';
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeSkill">
<div id="EmployeeSkill" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeSkillForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeEducation">
<div id="EmployeeEducation" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeEducationForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeCertification">
<div id="EmployeeCertification" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeCertificationForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeLanguage">
<div id="EmployeeLanguage" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeLanguageForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeDependent">
<div id="EmployeeDependent" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeDependentForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmergencyContact">
<div id="EmergencyContact" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmergencyContactForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageArchivedEmployee">
<div id="ArchivedEmployee" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="ArchivedEmployeeForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageTerminatedEmployee">
<div id="TerminatedEmployee" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="TerminatedEmployeeForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<?php if (!class_exists('DocumentsAdminManager')) {?>
<div class="tab-pane" id="tabPageEmployeeDocument">
<div id="EmployeeDocument" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeDocumentForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<?php } ?>
</div>
</div>
<script>
var modJsList = new Array();
modJsList['tabEmployee'] = new EmployeeAdapter('Employee');
<?php if($user->user_level != "Admin"){
?>
modJsList['tabEmployee'] = new EmployeeAdapter('Employee','Employee',{"status":"Active", "supervisor":"__myid__"});
modJsList['tabEmployee'].setShowAddNew(false);
<?php
}else{
?>
modJsList['tabEmployee'] = new EmployeeAdapter('Employee','Employee',{"status":"Active"});
<?php
}
?>
modJsList['tabEmployee'].setRemoteTable(true);
modJsList['tabEmployee'].setFieldNameMap(<?=json_encode($fieldNameMap)?>);
modJsList['tabEmployee'].setCustomFields(<?=json_encode($customFields)?>);
modJsList['tabEmployeeSkill'] = new EmployeeSkillAdapter('EmployeeSkill');
modJsList['tabEmployeeSkill'].setRemoteTable(true);
modJsList['tabEmployeeEducation'] = new EmployeeEducationAdapter('EmployeeEducation');
modJsList['tabEmployeeEducation'].setRemoteTable(true);
modJsList['tabEmployeeCertification'] = new EmployeeCertificationAdapter('EmployeeCertification');
modJsList['tabEmployeeCertification'].setRemoteTable(true);
modJsList['tabEmployeeLanguage'] = new EmployeeLanguageAdapter('EmployeeLanguage');
modJsList['tabEmployeeLanguage'].setRemoteTable(true);
modJsList['tabEmployeeDependent'] = new EmployeeDependentAdapter('EmployeeDependent');
modJsList['tabEmployeeDependent'].setRemoteTable(true);
modJsList['tabEmergencyContact'] = new EmergencyContactAdapter('EmergencyContact');
modJsList['tabEmergencyContact'].setRemoteTable(true);
modJsList['tabEmployeeImmigration'] = new EmployeeImmigrationAdapter('EmployeeImmigration');
modJsList['tabEmployeeImmigration'].setRemoteTable(true);
modJsList['tabArchivedEmployee'] = new ArchivedEmployeeAdapter('ArchivedEmployee');
modJsList['tabArchivedEmployee'].setRemoteTable(true);
modJsList['tabArchivedEmployee'].setShowAddNew(false);
modJsList['tabTerminatedEmployee'] = new TerminatedEmployeeAdapter('Employee','TerminatedEmployee',{"status":"Terminated"});
modJsList['tabTerminatedEmployee'].setRemoteTable(true);
modJsList['tabTerminatedEmployee'].setShowAddNew(false);
<?php if (!class_exists('DocumentsAdminManager')) {?>
modJsList['tabEmployeeDocument'] = new EmployeeDocumentAdapter('EmployeeDocument','EmployeeDocument');
modJsList['tabTerminatedEmployee'].setRemoteTable(true);
<?php } ?>
var modJs = modJsList['tabEmployee'];
</script>
<?php include APP_BASE_PATH.'footer.php';?>
<div class="modal" id="createUserModel" tabindex="-1" role="dialog" aria-labelledby="messageModelLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><li class="fa fa-times"/></button>
<h3 style="font-size: 17px;">Employee Saved Successfully</h3>
</div>
<div class="modal-body">
Employee needs a User to login to IceHrm. Do you want to create a user for this employee now? <br/><br/>You can do this later through Users module if required.
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="modJs.createUser();">Yes</button>
<button class="btn" onclick="modJs.closeCreateUser();">No</button>
</div>
</div>
</div>
</div>
<?php include APP_BASE_PATH.'footer.php';?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
<?php
if (!class_exists('FieldnamesAdminManager')) {
class FieldnamesAdminManager extends AbstractModuleManager{
public function initializeUserClasses(){
}
public function initializeFieldMappings(){
}
public function initializeDatabaseErrorMappings(){
}
public function setupModuleClassDefinitions(){
$this->addModelClass('FieldNameMapping');
$this->addModelClass('CustomField');
}
}
}
if (!class_exists('FieldNameMapping')) {
class FieldNameMapping extends ICEHRM_Record {
var $_table = 'FieldNameMappings';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array();
}
public function getAnonymousAccess(){
return array("get","element");
}
}
}
if (!class_exists('CustomField')) {
class CustomField extends ICEHRM_Record {
var $_table = 'CustomFields';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array();
}
public function getAnonymousAccess(){
return array("get","element");
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
This file is part of Ice Framework.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
*/
$moduleName = 'fieldnames';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
?><div class="span9">
<ul class="nav nav-tabs" id="modTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">
<li class="dropdown">
<a href="#" id="settingsEmployeeMenu" class="dropdown-toggle" data-toggle="dropdown" aria-controls="settingsEmployeeMenu-contents">Employee Fields <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu" aria-labelledby="settingsEmployeeMenu" id="settingsEmployeeMenu-contents">
<li><a id="tabEmployeeFieldName" href="#tabPageEmployeeFieldName">Employee Field Name Mapping</a></li>
<li><a id="tabEmployeeCustomField" href="#tabPageEmployeeCustomField">Employee Custom Fields</a></li>
</ul>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tabPageEmployeeFieldName">
<div id="EmployeeFieldName" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeFieldNameForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
<div class="tab-pane" id="tabPageEmployeeCustomField">
<div id="EmployeeCustomField" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="EmployeeCustomFieldForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
</div>
</div>
<script>
var modJsList = new Array();
modJsList['tabEmployeeFieldName'] = new FieldNameAdapter('FieldNameMapping','EmployeeFieldName',{"type":"Employee"});
modJsList['tabEmployeeFieldName'].setRemoteTable(true);
modJsList['tabEmployeeFieldName'].setShowAddNew(false);
modJsList['tabEmployeeCustomField'] = new CustomFieldAdapter('CustomField','EmployeeCustomField',{"type":"Employee"});
modJsList['tabEmployeeCustomField'].setRemoteTable(true);
modJsList['tabEmployeeCustomField'].setShowAddNew(false);
var modJs = modJsList['tabEmployeeFieldName'];
</script>
<?php include APP_BASE_PATH.'footer.php';?>

View File

@@ -0,0 +1,86 @@
/**
* Author: Thilina Hasantha
*/
/**
* FieldNameAdapter
*/
function FieldNameAdapter(endPoint,tab,filter,orderBy) {
this.initAdapter(endPoint,tab,filter,orderBy);
}
FieldNameAdapter.inherits(AdapterBase);
FieldNameAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"textOrig",
"textMapped",
"display"
];
});
FieldNameAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Original Text"},
{ "sTitle": "Mapped Text"},
{ "sTitle": "Display Status"}
];
});
FieldNameAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "type", {"label":"Type","type":"placeholder","validation":""}],
[ "name", {"label":"Name","type":"placeholder","validation":""}],
[ "textOrig", {"label":"Original Text","type":"placeholder","validation":""}],
[ "textMapped", {"label":"Mapped Text","type":"text","validation":""}],
[ "display", {"label":"Display Status","type":"select","source":[["Form","Form"],["Table and Form","Table and Form"],["Hidden","Hidden"]]}]
];
});
/*
*
*/
function CustomFieldAdapter(endPoint,tab,filter,orderBy) {
this.initAdapter(endPoint,tab,filter,orderBy);
}
CustomFieldAdapter.inherits(AdapterBase);
CustomFieldAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"display"
];
});
CustomFieldAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Display Status"}
];
});
CustomFieldAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "type", {"label":"Type","type":"placeholder","validation":""}],
[ "name", {"label":"Name","type":"placeholder","validation":""}],
[ "data", {"label":"Data","type":"textarea","validation":""}],
[ "display", {"label":"Display Status","type":"select","source":[["Form","Form"],["Table and Form","Table and Form"],["Hidden","Hidden"]]}]
];
});

View File

@@ -0,0 +1,11 @@
{
"label":"Field Names Setup",
"menu":"System",
"order":"7",
"icon":"fa-sort-alpha-asc",
"user_levels":["Admin"],
"permissions":
{
}
}

View File

@@ -3,5 +3,5 @@
"Employees":"fa-users",
"Reports":"fa-file-text",
"System":"fa-cogs",
"Salary Details":"fa-money"
"Payroll":"fa-money"
}

View File

@@ -22,6 +22,7 @@ if (!class_exists('MetadataAdminManager')) {
$this->addModelClass('Nationality');
$this->addModelClass('ImmigrationStatus');
$this->addModelClass('Ethnicity');
$this->addModelClass('CalculationHook');
}
}
@@ -42,6 +43,20 @@ if (!class_exists('Country')) {
public function getAnonymousAccess(){
return array("get","element");
}
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array()){
$allowedCountriesStr = SettingsManager::getInstance()->getSetting('System: Allowed Countries');
$allowedCountries = array();
if(!empty($allowedCountriesStr)){
$allowedCountries = json_decode($allowedCountriesStr,true);
}
if(!empty($allowedCountries)){
return parent::Find("id in (".implode(",",$allowedCountries).")" , array());
}
return parent::Find($whereOrderBy, $bindarr, $pkeysArr, $extra);
}
}
}
@@ -79,6 +94,20 @@ if (!class_exists('CurrencyType')) {
public function getAnonymousAccess(){
return array("get","element");
}
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array()){
$allowedCountriesStr = SettingsManager::getInstance()->getSetting('System: Allowed Currencies');
$allowedCountries = array();
if(!empty($allowedCountriesStr)){
$allowedCountries = json_decode($allowedCountriesStr,true);
}
if(!empty($allowedCountries)){
return parent::Find("id in (".implode(",",$allowedCountries).")" , array());
}
return parent::Find($whereOrderBy, $bindarr, $pkeysArr, $extra);
}
}
}
@@ -98,6 +127,22 @@ if (!class_exists('Nationality')) {
public function getAnonymousAccess(){
return array("get","element");
}
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array()){
$allowedCountriesStr = SettingsManager::getInstance()->getSetting('System: Allowed Nationality');
$allowedCountries = array();
if(!empty($allowedCountriesStr)){
$allowedCountries = json_decode($allowedCountriesStr,true);
}
if(!empty($allowedCountries)){
return parent::Find("id in (".implode(",",$allowedCountries).")" , array());
}
return parent::Find($whereOrderBy, $bindarr, $pkeysArr, $extra);
}
}
}
@@ -139,6 +184,32 @@ if (!class_exists('Ethnicity')) {
}
}
if (!class_exists('CalculationHook')) {
class CalculationHook extends ICEHRM_Record {
var $_table = 'CalculationHooks';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array();
}
public function getAnonymousAccess(){
return array("get","element");
}
function Find($whereOrderBy,$bindarr=false,$pkeysArr=false,$extra=array()){
return BaseService::getInstance()->getCalculationHooks();
}
function Load($where=null,$bindarr=false){
return BaseService::getInstance()->getCalculationHook($bindarr[0]);
}
}
}

View File

@@ -32,7 +32,6 @@ $moduleBuilder->addModuleOrGroup(new ModuleTab('Country','Country','Countries','
$moduleBuilder->addModuleOrGroup(new ModuleTab('Province','Province','Provinces','ProvinceAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('CurrencyType','CurrencyType','Currency Types','CurrencyTypeAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('Nationality','Nationality','Nationality','NationalityAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('Nationality','Nationality','Nationality','NationalityAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('Ethnicity','Ethnicity','Ethnicity','EthnicityAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('ImmigrationStatus','ImmigrationStatus','Immigration Status','ImmigrationStatusAdapter','',''));

View File

@@ -46,9 +46,9 @@ include APP_BASE_PATH.'modulejslibs.inc.php';
<script>
var modJsList = new Array();
modJsList['moduleModule'] = new ModuleAdapter('Module','Module');
modJsList['moduleModule'].setShowAddNew(false);
var modJs = modJsList['moduleModule'];
modJsList['tabModule'] = new ModuleAdapter('Module','Module');
modJsList['tabModule'].setShowAddNew(false);
var modJs = modJsList['tabModule'];
</script>
<?php include APP_BASE_PATH.'footer.php';?>

View File

@@ -58,7 +58,7 @@ ModuleAdapter.method('getActionButtonsHtml', function(id,data) {
var nonEditableFields = {};
nonEditableFields["admin_Company Structure"] = 1;
nonEditableFields["admin_Employees"] = 1;
nonEditableFields["admin_Jobs"] = 1;
nonEditableFields["admin_Job Details Setup"] = 1;
nonEditableFields["admin_Leaves"] = 1;
nonEditableFields["admin_Manage Modules"] = 1;
nonEditableFields["admin_Projects"] = 1;
@@ -66,10 +66,11 @@ ModuleAdapter.method('getActionButtonsHtml', function(id,data) {
nonEditableFields["admin_Settings"] = 1;
nonEditableFields["admin_Users"] = 1;
nonEditableFields["admin_Upgrade"] = 1;
nonEditableFields["admin_Upgrade"] = 1;
nonEditableFields["admin_Dashboard"] = 1;
nonEditableFields["user_Basic Information"] = 1;
nonEditableFields["user_Dashboard"] = 1;
if(nonEditableFields[data[3]+"_"+data[1]] == 1){
return "";
}

View File

@@ -1,11 +0,0 @@
{
"label":"Setup",
"menu":"Salary Details",
"order":"6",
"icon":"fa-cogs",
"user_levels":["Admin"],
"permissions":
{
}
}

View File

@@ -32,33 +32,49 @@ from EmployeeLeaves lv";
if(in_array("NULL", $employeeList) ){
$employeeList = array();
}
if($request['department'] != "NULL" && empty($employeeList)){
$empTmp = new Employee();
$empTemps = $empTmp->Find("department = ? and status = Active",array($request['department']));
foreach($empTemps as $empTmp){
$employeeList[] = $empTmp->id;
}
}
if(!empty($employeeList) && ($request['status'] != "NULL" && !empty($request['status']))){
$query = "where employee in (".implode(",", $employeeList).") and date_start >= ? and date_end <= ? and status = ?;";
$query = "where employee in (".implode(",", $employeeList).") and ((date_start >= ? and date_start <= ?) or (date_end >= ? and date_end <= ?)) and status = ?;";
$params = array(
$request['date_start'],
$request['date_end'],
$request['date_end'],
$request['date_start'],
$request['date_end'],
$request['status']
);
}else if(!empty($employeeList)){
$query = "where employee in (".implode(",", $employeeList).") and date_start >= ? and date_end <= ?;";
$query = "where employee in (".implode(",", $employeeList).") and ((date_start >= ? and date_start <= ?) or (date_end >= ? and date_end <= ?));";
$params = array(
$request['date_start'],
$request['date_end'],
$request['date_start'],
$request['date_end']
);
}else if(($request['status'] != "NULL" && !empty($request['status']))){
$query = "where status = ? and date_start >= ? and date_end <= ?;";
$query = "where status = ? and ((date_start >= ? and date_start <= ?) or (date_end >= ? and date_end <= ?));";
$params = array(
$request['status'],
$request['date_start'],
$request['date_end']
$request['date_end'],
$request['date_start'],
$request['date_end']
);
}else{
$query = "where date_start >= ? and date_end <= ?;";
$query = "where ((date_start >= ? and date_start <= ?) or (date_end >= ? and date_end <= ?));";
$params = array(
$request['date_start'],
$request['date_end']
$request['date_end'],
$request['date_start'],
$request['date_end']
);
}

View File

@@ -0,0 +1,44 @@
ICEHRM END USER LICENSE AGREEMENT
NOTICE TO ALL USERS: BY PURCHASING THE MODULE, YOU (EITHER AN INDIVIDUAL OR A SINGLE ENTITY) CONSENT TO BE BOUND BY AND BECOME A PARTY TO THIS AGREEMENT.
All references to "Software" herein shall be deemed to include the software license with which you will be provided by Gamonoid Media Pvt Ltd, as part of the Software.
1. LICENSE GRANT. Subject to the payment of the applicable licence fees, and subject to the terms and conditions of this Agreement, ICEHRM hereby grants to you a non-exclusive, non-transferable right to use one copy of the specified version of the Software and the accompanying documentation (the "Documentation") for the term of this Agreement solely for your own internal business purposes. You may install one copy of the Software for production use.
.
2. USE. The Software is licensed as a single product; it may not be used on more than one ICEHRM Server at a time. The Software is "in use" on a Server when its installed on a Server. You shall not, nor permit any third party to copy (other than as expressly permitted herein). You shall not rent, lease or lend the Software to any other person, nor transfer or sub-licence your licence rights to any other person.
3. TERM. This Agreement is effective until terminated as set forth herein. This Agreement will terminate automatically if you fail to comply with any of the conditions, limitations or other requirements described herein. Upon any termination of this Agreement, you must immediately destroy all copies of the Software and the Documentation. You may terminate this Agreement at any point by destroying all copies of the Software and the Documentation.
4. SUPPORT. Gamonoid Media Pvt Ltd will provide you support according to the support agreement subscribed by the company.
5. OWNERSHIP RIGHTS. The Software is protected by copyright laws. ICEHRM and Gamonoid Media Pvt Ltd own and retain all right, title and interest in and to the Software, including all copyrights, patents, trademarks and other intellectual property rights therein. Your possession, installation, or use of the Software does not transfer to you any title to the intellectual property in the Software, and you will not acquire any rights to the Software except as expressly set forth in this Agreement.
6. LIMITED WARRANTY. You may not rent, lease, loan or resell the Software. You may not permit third parties to benefit from the use or functionality of the Software via a timesharing, service bureau or other arrangement, except to the extent such use is specified in the applicable list price or product packaging for the Software. You may not transfer any of the rights granted to you under this Agreement. You may not modify, or create derivative works based upon, the Software in whole or in part. You may not copy the Software or Documentation except as expressly permitted in Section 1 above. You may not remove any proprietary notices or labels on the Software. All rights not expressly set forth hereunder are reserved by ICEHRM. ICEHRM reserves the right to periodically conduct audits upon advance written notice to verify compliance with the terms of this Agreement.
7. WARRANTY and DISCLAIMER.
(i) Gamonoid Media Pvt Ltd. warrants that for 30 days from first download or installation the Software will perform substantially in accordance with the functionality described in the Documentation (http://blog.icehrm.com) when operated properly and in the manner specified in the Documentation.
(ii) You accept all responsibility for the selection of this Software to meet your requirements.
(iii) Gamonoid Media Pvt Ltd. does not warrant that the Software and/or the Documentation will be suitable for such requirements nor that any use will be uninterrupted and error free.
(iv) The warranty in (i) shall not apply if you (a) make or cause to be made any modifications to this Software, (b) use the Software in a manner for which it was not intended or (c) use the Software other than as permitted under this Agreement.
(vii) The warranties and conditions stated in this Agreement are in lieu of all other conditions, warranties or other terms concerning the supply or purported supply of, failure to supply or delay in supplying the Software or the Documentation which might but for this paragraph (vii) have effect between the ICEHRM and you or would otherwise be implied into or incorporated into this Agreement or any collateral contract, whether by statute, common law or otherwise, all of which are hereby excluded (including, without limitation, the implied conditions, warranties or other terms as to satisfactory quality, fitness for purpose or as to the use of reasonable skill and care).
8. LIMITATION of LIABILITY. Gamonoid Media Pvt Ltd. shall have no liability (whether in contract, tort, restitution or otherwise) for any of the following losses or damage (whether such losses or damage were foreseen, foreseeable, known or otherwise):
- Loss of revenue;
- Loss of actual or anticipated profits (including for loss of profits on contracts);
- Loss of the use of money;
- Loss of anticipated savings;
- Loss of business;
- Loss of opportunity;
- Loss of goodwill;
- Loss of reputation;
- Loss of, damage to or corruption of data;
or
Any indirect or consequential loss or damage howsoever caused (including, for the avoidance of doubt, where such loss or damage is of the type specified in paragraph (ii), (a) to (ii), (i).
The ICEHRM liability (whether in contract, tort, restitution or otherwise) arising out of or in connection with the supply of the Software shall in no circumstances exceed a sum equal to the amount equally paid by you for the Software.
The construction and interpretation of this Agreement shall be governed in accordance with the laws of Sri Lanka. The parties hereby submit to the jurisdiction of the courts of Sri Lanka save that ICEHRM as claimant shall be entitled to initiate proceedings in any court of competent jurisdiction.
This Agreement contains the entire understanding of the parties with respect to the subject matter hereof and supersedes all and any prior understandings, undertakings and promises between you and ICEHRM, whether oral or in writing, which have been given or may be implied from anything written or said in negotiations between us or our representatives prior to this Agreement and all prior agreements between the parties relating to the matters aforesaid shall cease to have effect as from the Effective Date.

View File

@@ -0,0 +1,7 @@
This module is licensed under IceHrm Commercial License, which can be found in LICENSE.txt.
You are allowed to make any modification required to these module, but only allowed to use
the module in one production server (even with modifications).
Installation
------------
Copy this module into <icehrm path>/admin/ directory

View File

@@ -1,6 +1,6 @@
<?php
if (!class_exists('PayrollAdminManager')) {
class PayrollAdminManager extends AbstractModuleManager{
if (!class_exists('SalaryAdminManager')) {
class SalaryAdminManager extends AbstractModuleManager{
public function initializeUserClasses(){
@@ -18,7 +18,6 @@ if (!class_exists('PayrollAdminManager')) {
$this->addModelClass('SalaryComponentType');
$this->addModelClass('SalaryComponent');
$this->addModelClass('Deduction');
}
}
@@ -66,4 +65,31 @@ if (!class_exists('Deduction')) {
}
}
if (!class_exists('DeductionGroup')) {
class DeductionGroup extends ICEHRM_Record {
var $_table = 'DeductionGroup';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array("get","element");
}
}
}
if (!class_exists('PayrollEmployee')) {
class PayrollEmployee extends ICEHRM_Record {
var $_table = 'PayrollEmployees';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array("get","element");
}
}
}

View File

@@ -1,15 +1,18 @@
<?php
$moduleName = 'metadata';
$moduleName = 'salary';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
include APP_BASE_PATH.'mod-houlejslibs.inc.php';
$moduleBuilder = new ModuleBuilder();
$moduleBuilder->addModuleOrGroup(new ModuleTab('SalaryComponentType','SalaryComponentType','Salary Component Types','SalaryComponentTypeAdapter','','',true));
$moduleBuilder->addModuleOrGroup(new ModuleTab('SalaryComponent','SalaryComponent','Salary Components','SalaryComponentAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('EmployeeSalary','EmployeeSalary','Employee Salary','EmployeeSalaryAdapter','','',false,array("setRemoteTable"=>"true")));
$moduleBuilder->addModuleOrGroup(new ModuleTab('DeductionGroup','DeductionGroup','Calculation Groups','DeductionGroupAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('Deduction','Deduction','Calculation Methods','DeductionAdapter','',''));
$moduleBuilder->addModuleOrGroup(new ModuleTab('EmployeeSalary','EmployeeSalary','Employee Salary Components','EmployeeSalaryAdapter','','',false,array("setRemoteTable"=>"true")));
echo UIManager::getInstance()->renderModule($moduleBuilder);

View File

@@ -2,7 +2,6 @@
* Author: Thilina Hasantha
*/
/**
* SalaryComponentTypeAdapter
*/
@@ -16,27 +15,27 @@ SalaryComponentTypeAdapter.inherits(AdapterBase);
SalaryComponentTypeAdapter.method('getDataMapping', function() {
return [
"id",
"code",
"name"
];
return [
"id",
"code",
"name"
];
});
SalaryComponentTypeAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Code" },
{ "sTitle": "Name"}
];
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Code" },
{ "sTitle": "Name"}
];
});
SalaryComponentTypeAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "code", {"label":"Code","type":"text","validation":""}],
[ "name", {"label":"Name","type":"text","validation":""}]
];
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "code", {"label":"Code","type":"text","validation":""}],
[ "name", {"label":"Name","type":"text","validation":""}]
];
});
@@ -53,30 +52,30 @@ SalaryComponentAdapter.inherits(AdapterBase);
SalaryComponentAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"componentType",
"details"
];
return [
"id",
"name",
"componentType",
"details"
];
});
SalaryComponentAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Salary Component Type" },
{ "sTitle": "Details"}
];
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Salary Component Type" },
{ "sTitle": "Details"}
];
});
SalaryComponentAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "name", {"label":"Name","type":"text","validation":""}],
[ "componentType", {"label":"Salary Component Type","type":"select2","remote-source":["SalaryComponentType","id","name"]}],
[ "details", {"label":"Details","type":"textarea","validation":"none"}]
];
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "name", {"label":"Name","type":"text","validation":""}],
[ "componentType", {"label":"Salary Component Type","type":"select2","remote-source":["SalaryComponentType","id","name"]}],
[ "details", {"label":"Details","type":"textarea","validation":"none"}]
];
});
@@ -96,8 +95,7 @@ DeductionAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"contributor",
"type",
"deduction_group"
];
});
@@ -105,32 +103,52 @@ DeductionAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Contributor"},
{ "sTitle": "Deduction Type"}
{ "sTitle": "Calculation Group"}
];
});
DeductionAdapter.method('getFormFields', function() {
var rangeAmounts = [ "rangeAmounts", {"label":"Deduction Amounts","type":"datagroup",
var rangeAmounts = [ "rangeAmounts", {"label":"Calculation Process","type":"datagroup",
"form":[
[ "lowerCondition", {"label":"Lower Limit Condition","type":"select","source":[["No Lower Limit","No Lower Limit"],[">","Greater than"],[">=","Greater than or Equal"]]}],
[ "lowerLimit", {"label":"Lower Limit","type":"text","validation":"none"}],
[ "upperCondition", {"label":"Upper Limit Condition","type":"select","source":[["No Upper Limit","No Upper Limit"],["<","Less than"],["<=","Less than or Equal"]]}],
[ "upperLimit", {"label":"Upper Limit","type":"text","validation":"none"}],
[ "amount", {"label":"Value","type":"text","validation":"float"}]
[ "lowerCondition", {"label":"Lower Limit Condition","type":"select","source":[["No Lower Limit","No Lower Limit"],["gt","Greater than"],["gte","Greater than or Equal"]]}],
[ "lowerLimit", {"label":"Lower Limit","type":"text","validation":"float"}],
[ "upperCondition", {"label":"Upper Limit Condition","type":"select","source":[["No Upper Limit","No Upper Limit"],["lt","Less than"],["lte","Less than or Equal"]]}],
[ "upperLimit", {"label":"Upper Limit","type":"text","validation":"float"}],
[ "amount", {"label":"Value","type":"text","validation":""}]
],
"html":'<div id="#_id_#" class="panel panel-default">#_delete_##_edit_#<div class="panel-body">#_renderFunction_#</div></div>',
"validation":"none",
"custom-validate-function":function (data){
var res = {};
res['valid'] = true;
if(lowerCondition != 'No Lower Limit'){
data.lowerLimit = 0;
}
if(upperCondition != 'No Upper Limit'){
data.upperLimit = 0;
}
res['params'] = data;
return res;
},
"render":function(item){
var output = "";
var getSymbol = function(text){
var map = {};
map['gt'] = '>';
map['gte'] = '>=';
map['lt'] = '<';
map['lte'] = '<=';
return map[text];
}
if(item.lowerCondition != "No Lower Limit"){
output += item.lowerLimit + " " + item.lowerCondition + " ";
output += " and ";
output += item.lowerLimit + " " + getSymbol(item.lowerCondition) + " ";
}
if(item.upperCondition != "No Upper Limit"){
output += item.upperCondition + " " + item.upperLimit + " ";
output += " and ";
output += getSymbol(item.upperCondition) + " " + item.upperLimit + " ";
}
if(output == ""){
return "Deduction is "+item.amount + " for all ranges";
@@ -148,17 +166,16 @@ DeductionAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "name", {"label":"Name","type":"text","validation":""}],
[ "contributor", {"label":"Contributor","type":"select","source":[["Employee","Employee"],["Employer","Employer"]]}],
[ "type", {"label":"Deduction Type","type":"select","source":[["Fixed","Fixed"],["Percentage","Percentage"]]}],
[ "percentage_type", {"label":"Percentage Type","type":"select","source":[["On Component","On Component"],["On Component Type","On Component Type"]]}],
[ "componentType", {"label":"Salary Component Type","type":"select2","allow-null":true,"null-label":"N/A","remote-source":["SalaryComponentType","id","name"]}],
[ "component", {"label":"Salary Component","type":"select2","allow-null":true,"null-label":"N/A","remote-source":["SalaryComponent","id","name"]}],
[ "componentType", {"label":"Salary Component Type","type":"select2multi","allow-null":true,"remote-source":["SalaryComponentType","id","name"]}],
[ "component", {"label":"Salary Component","type":"select2multi","allow-null":true,"remote-source":["SalaryComponent","id","name"]}],
[ "payrollColumn", {"label":"Payroll Report Column","type":"select2","allow-null":true,"remote-source":["PayrollColumn","id","name"]}],
rangeAmounts,
[ "country", {"label":"Country","type":"select2","remote-source":["Country","id","name"]}]
[ "deduction_group", {"label":"Calculation Group","type":"select2","allow-null":true,"null-label":"None","remote-source":["DeductionGroup","id","name"]}]
];
});
/*
DeductionAdapter.method('doCustomValidation', function(params) {
if(params.type == "Fixed"){
return null;
@@ -177,7 +194,8 @@ DeductionAdapter.method('doCustomValidation', function(params) {
return null;
});
*/
/*
DeductionAdapter.method('postRenderForm', function(object, $tempDomObj) {
$tempDomObj.find("#field_componentType").hide();
@@ -213,6 +231,10 @@ DeductionAdapter.method('postRenderForm', function(object, $tempDomObj) {
}
});
});
*/
/*
@@ -232,8 +254,6 @@ EmployeeSalaryAdapter.method('getDataMapping', function() {
"id",
"employee",
"component",
"pay_frequency",
"currency",
"amount",
"details"
];
@@ -244,8 +264,6 @@ EmployeeSalaryAdapter.method('getHeaders', function() {
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Employee" },
{ "sTitle": "Salary Component" },
{ "sTitle": "Pay Frequency"},
{ "sTitle": "Currency"},
{ "sTitle": "Amount"},
{ "sTitle": "Details"}
];
@@ -256,8 +274,6 @@ EmployeeSalaryAdapter.method('getFormFields', function() {
[ "id", {"label":"ID","type":"hidden"}],
[ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}],
[ "component", {"label":"Salary Component","type":"select2","remote-source":["SalaryComponent","id","name"]}],
[ "pay_frequency", {"label":"Pay Frequency","type":"select","source":[["Hourly","Hourly"],["Daily","Daily"],["Bi Weekly","Bi Weekly"],["Weekly","Weekly"],["Semi Monthly","Semi Monthly"],["Monthly","Monthly"]]}],
[ "currency", {"label":"Currency","type":"select2","remote-source":["CurrencyType","id","name"]}],
[ "amount", {"label":"Amount","type":"text","validation":"float"}],
[ "details", {"label":"Details","type":"textarea","validation":"none"}]
];
@@ -272,3 +288,43 @@ EmployeeSalaryAdapter.method('getFilters', function() {
/*
* DeductionGroupAdapter
*/
function DeductionGroupAdapter(endPoint,tab,filter,orderBy) {
this.initAdapter(endPoint,tab,filter,orderBy);
}
DeductionGroupAdapter.inherits(AdapterBase);
DeductionGroupAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"description"
];
});
DeductionGroupAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Details" }
];
});
DeductionGroupAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "name", {"label":"Name","type":"text","validation":""}],
[ "description", {"label":"Details","type":"textarea","validation":"none"}]
];
});

View File

@@ -0,0 +1,11 @@
{
"label":"Salary",
"menu":"Payroll",
"order":"1",
"icon":"fa-money",
"user_levels":["Admin"],
"permissions":
{
}
}

View File

@@ -22,7 +22,7 @@ Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilin
*/
class SettingsInitialize extends AbstractInitialize{
public function init(){
if(SettingsManager::getInstance()->getSetting("Api: REST Api Enabled") == "1"){
$user = BaseService::getInstance()->getCurrentUser();
@@ -30,7 +30,7 @@ class SettingsInitialize extends AbstractInitialize{
$dbUser->Load("id = ?",array($user->id));
$resp = RestApiManager::getInstance()->getAccessTokenForUser($dbUser);
if($resp->getStatus() != IceResponse::SUCCESS){
LogManager::getInstance()->error("Error occured while creating REST Api acces token for ".$user->username);
LogManager::getInstance()->error("Error occurred while creating REST Api access token for ".$user->username);
}
}

View File

@@ -25,37 +25,26 @@ $moduleName = 'settings';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
?><div class="span9">
<ul class="nav nav-tabs" id="modTab" style="margin-bottom:0px;margin-left:5px;border-bottom: none;">
<li class="active"><a id="tabSetting" href="#tabPageSetting">Settings</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tabPageSetting">
<div id="Setting" class="reviewBlock" data-content="List" style="padding-left:5px;">
</div>
<div id="SettingForm" class="reviewBlock" data-content="Form" style="padding-left:5px;display:none;">
</div>
</div>
</div>
$moduleBuilder = new ModuleBuilder();
$options1 = array();
$options1['setShowAddNew'] = 'false';
$moduleBuilder->addModuleOrGroup(new ModuleTab('CompanySetting','Setting','Company','SettingAdapter','{"name":["Company:"]}','name',true,$options1));
$moduleBuilder->addModuleOrGroup(new ModuleTab('SystemSetting','Setting','System','SettingAdapter','{"name":["System:"]}','name',false,$options1));
$moduleBuilder->addModuleOrGroup(new ModuleTab('EmailSetting','Setting','Email','SettingAdapter','{"name":["Email:"]}','name',false,$options1));
$moduleBuilder->addModuleOrGroup(new ModuleTab('LeaveSetting','Setting','Leave / PTO','SettingAdapter','{"name":["Leave:"]}','name',false,$options1));
$moduleBuilder->addModuleOrGroup(new ModuleTab('LDAPSetting','Setting','LDAP','SettingAdapter','{"name":["LDAP:"]}','name',false,$options1));
$moduleBuilder->addModuleOrGroup(new ModuleTab('OtherSetting','Setting','Other','SettingAdapter','{"name":["Projects:","Attendance:","Recruitment:","Notifications:","Expense:","Travel:","Api:"]}','name',false,$options1));
echo UIManager::getInstance()->renderModule($moduleBuilder);
?>
</div>
<script>
var modJsList = new Array();
modJsList['tabSetting'] = new SettingAdapter('Setting','Setting','','name');
modJsList['tabSetting'].setShowAddNew(false);
var modJs = modJsList['tabSetting'];
$(window).load(function() {
modJs.loadRemoteDataForSettings();
});
</script>
<?php include APP_BASE_PATH.'footer.php';?>

View File

@@ -62,24 +62,46 @@ SettingAdapter.method('edit', function(id) {
SettingAdapter.method('fillForm', function(object) {
this.uber('fillForm',object);
var metaField = this.getMetaFieldForRendering('value');
var metaVal = object[metaField];
var formFields = null;
if(metaVal != "" && metaVal != undefined){
var formFields = [
[ "id", {"label":"ID","type":"hidden"}],
JSON.parse(metaVal)
];
}
this.uber('fillForm',object, null, formFields);
$("#helptext").html(object.description);
});
SettingAdapter.method('loadRemoteDataForSettings', function () {
var field = ["country", {"label": "Country", "type": "select2", "remote-source": ["Country", "code", "name"]}];
if (field[1]['remote-source'] != undefined && field[1]['remote-source'] != null) {
var key = field[1]['remote-source'][0] + "_" + field[1]['remote-source'][1] + "_" + field[1]['remote-source'][2];
this.fieldMasterDataKeys[key] = false;
this.sourceMapping[field[0]] = field[1]['remote-source'];
var fields = [];
var field = null;
fields.push(["country", {"label": "Country", "type": "select2multi", "remote-source": ["Country", "id", "name"]}]);
fields.push(["currency", {"label": "Currency", "type": "select2multi", "remote-source": ["CurrencyType","id","code+name"]}]);
fields.push(["nationality", {"label": "Nationality", "type": "select2multi", "remote-source": ["Nationality","id","name"]}]);
var callBackData = {};
callBackData['callBack'] = 'initFieldMasterDataResponse';
callBackData['callBackData'] = [key];
for(index in fields){
field = fields[index];
if (field[1]['remote-source'] != undefined && field[1]['remote-source'] != null) {
var key = field[1]['remote-source'][0] + "_" + field[1]['remote-source'][1] + "_" + field[1]['remote-source'][2];
this.fieldMasterDataKeys[key] = false;
this.sourceMapping[field[0]] = field[1]['remote-source'];
var callBackData = {};
callBackData['callBack'] = 'initFieldMasterDataResponse';
callBackData['callBackData'] = [key];
this.getFieldValues(field[1]['remote-source'], callBackData);
}
}
this.getFieldValues(field[1]['remote-source'], callBackData);
}
});

View File

@@ -1,19 +0,0 @@
<?php
class TravelActionManager extends ApproveAdminActionManager{
public function getModelClass(){
return "EmployeeTravelRecord";
}
public function getItemName(){
return "TravelRequest";
}
public function getModuleName(){
return "Travel Management";
}
public function getModuleTabUrl(){
return "g=modules&n=travel&m=module_Travel_Management";
}
}

View File

@@ -1,128 +0,0 @@
<?php
if (!class_exists('TravelAdminManager')) {
class TravelAdminManager extends AbstractModuleManager{
public function initializeUserClasses(){
if(defined('MODULE_TYPE') && MODULE_TYPE != 'admin'){
$this->addUserClass("EmployeeImmigration");
$this->addUserClass("EmployeeTravelRecord");
}
}
public function initializeFieldMappings(){
$this->addFileFieldMapping('EmployeeImmigration', 'attachment1', 'name');
$this->addFileFieldMapping('EmployeeImmigration', 'attachment2', 'name');
$this->addFileFieldMapping('EmployeeImmigration', 'attachment3', 'name');
$this->addFileFieldMapping('EmployeeTravelRecord', 'attachment1', 'name');
$this->addFileFieldMapping('EmployeeTravelRecord', 'attachment2', 'name');
$this->addFileFieldMapping('EmployeeTravelRecord', 'attachment3', 'name');
}
public function initializeDatabaseErrorMappings(){
}
public function setupModuleClassDefinitions(){
$this->addModelClass('ImmigrationDocument');
$this->addModelClass('EmployeeImmigration');
$this->addModelClass('EmployeeTravelRecord');
}
}
}
if (!class_exists('ImmigrationDocument')) {
class ImmigrationDocument extends ICEHRM_Record {
var $_table = 'ImmigrationDocuments';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getManagerAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array("get");
}
public function getUserOnlyMeAccess(){
return array("get","element");
}
}
}
if (!class_exists('EmployeeImmigration')) {
class EmployeeImmigration extends ICEHRM_Record {
var $_table = 'EmployeeImmigrations';
public function getAdminAccess(){
return array("get","element","save","delete");
}
public function getManagerAccess(){
return array("get","element","save","delete");
}
public function getUserAccess(){
return array("get");
}
public function getUserOnlyMeAccess(){
return array("element","save","delete");
}
}
}
if (!class_exists('EmployeeTravelRecord')) {
class EmployeeTravelRecord extends ApproveModel
{
var $_table = 'EmployeeTravelRecords';
var $notificationModuleName = "Travel Management";
var $notificationUnitName = "TravelRequest";
var $notificationUnitPrefix = "A";
var $notificationUnitAdminUrl = "g=admin&n=travel&m=admin_Employees";
var $preApproveSettingName = "Travel: Pre-Approve Travel Request";
public function getAdminAccess()
{
return array("get", "element", "save", "delete");
}
public function getManagerAccess()
{
return array("get", "element", "save", "delete");
}
public function getUserAccess()
{
return array("get");
}
public function getUserOnlyMeAccess()
{
return array("element", "save", "delete");
}
public function fieldsNeedToBeApproved()
{
return array(
"travel_from",
"travel_to",
"travel_date",
"return_date",
"funding",
"currency"
);
}
}
}

View File

@@ -1,19 +0,0 @@
<div class="col-lg-3 col-xs-12">
<div class="small-box bg-red">
<div class="inner">
<h3>
Travel
</h3>
<p id="numberOfTravel">
Requests
</p>
</div>
<div class="icon">
<i class="ion ion-plane"></i>
</div>
<a href="#_moduleLink_#" class="small-box-footer" id="travelLink">
Manage Travel <i class="fa fa-arrow-circle-right"></i>
</a>
</div>
</div>

View File

@@ -1,78 +0,0 @@
<?php
/*
This file is part of iCE Hrm.
iCE Hrm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
iCE Hrm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with iCE Hrm. If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------------------
Original work Copyright (c) 2012 [Gamonoid Media Pvt. Ltd]
Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilinah)
*/
$moduleName = 'travel';
define('MODULE_PATH',dirname(__FILE__));
include APP_BASE_PATH.'header.php';
include APP_BASE_PATH.'modulejslibs.inc.php';
$options = array();
$options['setRemoteTable'] = 'true';
$moduleBuilder = new ModuleBuilder();
$moduleBuilder->addModuleOrGroup(new ModuleTab('EmployeeTravelRecord','EmployeeTravelRecord','Travel Requests','EmployeeTravelRecordAdapter','','',true,$options));
echo UIManager::getInstance()->renderModule($moduleBuilder);
$itemName = 'TravelRequest';
$moduleName = 'Travel Management';
$itemNameLower = strtolower($itemName);
$statuses = array("Approved","Pending","Rejected","Cancelled");
?><div class="modal" id="<?=$itemNameLower?>StatusModel" tabindex="-1" role="dialog" aria-labelledby="messageModelLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><li class="fa fa-times"/></button>
<h3 style="font-size: 17px;">Change <?=$itemName?> Status</h3>
</div>
<div class="modal-body">
<form id="expenseStatusForm">
<div class="control-group">
<label class="control-label" for="expense_status"><?=$itemName?> Status</label>
<div class="controls">
<select type="text" id="<?=$itemNameLower?>_status" class="form-control" name="<?=$itemNameLower?>_status" value="">
<?php foreach($statuses as $status){?>
<option value="<?=$status?>"><?=$status?></option>
<?php }?>
</select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="expense_status">Status Change Note</label>
<div class="controls">
<textarea id="<?=$itemNameLower?>_reason" class="form-control" name="<?=$itemNameLower?>_reason" maxlength="500"></textarea>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="modJs.changeStatus();">Change <?=$itemName?> Status</button>
<button class="btn" onclick="modJs.closeDialog();">Not Now</button>
</div>
</div>
</div>
</div>
<?php
include APP_BASE_PATH.'footer.php';

View File

@@ -1,182 +0,0 @@
/**
* Author: Thilina Hasantha
*/
/**
* ImmigrationDocumentAdapter
*/
function ImmigrationDocumentAdapter(endPoint) {
this.initAdapter(endPoint);
}
ImmigrationDocumentAdapter.inherits(AdapterBase);
ImmigrationDocumentAdapter.method('getDataMapping', function() {
return [
"id",
"name",
"details",
"required",
"alert_on_missing",
"alert_before_expiry"
];
});
ImmigrationDocumentAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Name" },
{ "sTitle": "Details"},
{ "sTitle": "Compulsory"},
{ "sTitle": "Alert If Not Found"},
{ "sTitle": "Alert Before Expiry"}
];
});
ImmigrationDocumentAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "name", {"label":"Name","type":"text","validation":""}],
[ "details", {"label":"Details","type":"textarea","validation":"none"}],
[ "required", {"label":"Compulsory","type":"select","source":[["No","No"],["Yes","Yes"]]}],
[ "alert_on_missing", {"label":"Alert If Not Found","type":"select","source":[["No","No"],["Yes","Yes"]]}],
[ "alert_before_expiry", {"label":"Alert Before Expiry","type":"select","source":[["No","No"],["Yes","Yes"]]}],
[ "alert_before_day_number", {"label":"Days for Expiry Alert","type":"text","validation":""}]
];
});
/**
* EmployeeImmigrationAdapter
*/
function EmployeeImmigrationAdapter(endPoint) {
this.initAdapter(endPoint);
}
EmployeeImmigrationAdapter.inherits(AdapterBase);
EmployeeImmigrationAdapter.method('getDataMapping', function() {
return [
"id",
"employee",
"document",
"documentname",
"valid_until",
"status"
];
});
EmployeeImmigrationAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Employee" },
{ "sTitle": "Document" },
{ "sTitle": "Document Id" },
{ "sTitle": "Valid Until"},
{ "sTitle": "Status"}
];
});
EmployeeImmigrationAdapter.method('getFormFields', function() {
return [
[ "id", {"label":"ID","type":"hidden"}],
[ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}],
[ "document", {"label":"Document","type":"select2","remote-source":["ImmigrationDocument","id","name"]}],
[ "documentname", {"label":"Document Id","type":"text","validation":""}],
[ "valid_until", {"label":"Valid Until","type":"date","validation":"none"}],
[ "status", {"label":"Status","type":"select","source":[["Active","Active"],["Inactive","Inactive"],["Draft","Draft"]]}],
[ "details", {"label":"Details","type":"textarea","validation":"none"}],
[ "attachment1", {"label":"Attachment 1","type":"fileupload","validation":"none"}],
[ "attachment2", {"label":"Attachment 2","type":"fileupload","validation":"none"}],
[ "attachment3", {"label":"Attachment 3","type":"fileupload","validation":"none"}]
];
});
EmployeeImmigrationAdapter.method('getFilters', function() {
return [
[ "employee", {"label":"Employee","type":"select2","remote-source":["Employee","id","first_name+last_name"]}]
];
});
/**
* EmployeeTravelRecordAdapter
*/
function EmployeeTravelRecordAdapter(endPoint,tab,filter,orderBy) {
this.initAdapter(endPoint,tab,filter,orderBy);
this.itemName = 'TravelRequest';
this.itemNameLower = 'travelrequest';
this.modulePathName = 'travel';
}
EmployeeTravelRecordAdapter.inherits(ApproveAdminAdapter);
EmployeeTravelRecordAdapter.method('getDataMapping', function() {
return [
"id",
"employee",
"type",
"purpose",
"travel_from",
"travel_to",
"travel_date",
"status"
];
});
EmployeeTravelRecordAdapter.method('getHeaders', function() {
return [
{ "sTitle": "ID" ,"bVisible":false},
{ "sTitle": "Employee" },
{ "sTitle": "Travel Type" },
{ "sTitle": "Purpose" },
{ "sTitle": "From"},
{ "sTitle": "To"},
{ "sTitle": "Travel Date"},
{ "sTitle": "Status"}
];
});
EmployeeTravelRecordAdapter.method('getFormFields', function() {
return [
["id", {"label": "ID", "type": "hidden"}],
["employee", {
"label": "Employee",
"type": "select2",
"sort": "none",
"allow-null": false,
"remote-source": ["Employee", "id", "first_name+last_name", "getActiveSubordinateEmployees"]
}],
["type", {
"label": "Travel Type",
"type": "select",
"source": [["Local", "Local"], ["International", "International"]]
}],
["purpose", {"label": "Purpose of Travel", "type": "textarea", "validation": ""}],
["travel_from", {"label": "Travel From", "type": "text", "validation": ""}],
["travel_to", {"label": "Travel To", "type": "text", "validation": ""}],
["travel_date", {"label": "Travel Date", "type": "datetime", "validation": ""}],
["return_date", {"label": "Return Date", "type": "datetime", "validation": ""}],
["details", {"label": "Notes", "type": "textarea", "validation": "none"}],
["currency", {"label": "Currency", "type": "select2", "allow-null":false, "remote-source": ["CurrencyType", "id", "code"]}],
["funding", {"label": "Total Funding Proposed", "type": "text", "validation": "float"}],
["attachment1", {"label": "Itinerary / Cab Receipt", "type": "fileupload", "validation": "none"}],
["attachment2", {"label": "Other Attachment 1", "type": "fileupload", "validation": "none"}],
["attachment3", {"label": "Other Attachment 2", "type": "fileupload", "validation": "none"}]
];
});

View File

@@ -1,12 +0,0 @@
{
"label":"Travel Administration",
"menu":"Employees",
"order":"6",
"icon":"fa-plane",
"user_levels":["Admin","Manager"],
"dashboardPosition":12,
"permissions":
{
}
}

View File

@@ -23,8 +23,16 @@ Developer: Thilina Hasantha (thilina.hasantha[at]gmail.com / facebook.com/thilin
class UsersActionManager extends SubActionManager{
public function changePassword($req){
if($this->user->user_level == 'Admin' || $this->user->id == $req->id){
$user = $this->baseService->getElement('User',$req->id);
if(defined('DEMO_MODE')){
return new IceResponse(IceResponse::ERROR,"You are not allowed to change the password in demo mode");
}
$user = new User();
$user->Load("id = ?",array($req->id));
LogManager::getInstance()->debug("Current User:".print_r($this->user,true));
LogManager::getInstance()->debug("Edit User:".print_r($user,true));
if($this->user->user_level == 'Admin' || $this->user->id == $user->id){
if(empty($user->id)){
return new IceResponse(IceResponse::ERROR,"Please save the user first");
}

View File

@@ -54,10 +54,39 @@ if (!class_exists('User')) {
if(count($users) > 0){
return new IceResponse(IceResponse::ERROR,"A user with same authentication email already exist");
}
//Check if you are trying to change user level
$oldUser = new User();
$oldUser->Load("id = ?",array($obj->id));
if($oldUser->user_level != $obj->user_level && $oldUser->user_level == 'Admin'){
$adminUsers = $userTemp->Find("user_level = ?",array("Admin"));
if(count($adminUsers) == 1 && $adminUsers[0]->id == $obj->id){
return new IceResponse(IceResponse::ERROR,"You are the only admin user for the application. You are not allowed to revoke your admin rights");
}
}
}
//Check if the user have rights to the default module
if(!empty($obj->default_module)){
$module = new Module();
$module->Load("id = ?",array($obj->default_module));
if($module->mod_group == "user"){
$module->mod_group = "modules";
}
$moduleManager = BaseService::getInstance()->getModuleManager($module->mod_group, $module->name);
if(!BaseService::getInstance()->isModuleAllowedForGivenUser($moduleManager, $obj)){
return new IceResponse(IceResponse::ERROR,"This module can not be set as the default module for the user since the user do not have access to this module");
}
}
return new IceResponse(IceResponse::SUCCESS,"");
}
var $_table = 'Users';
}