Upgrade to v26 (#172)

* A bunch of new updates from icehrm pro

* Push changes to frontend
This commit is contained in:
Thilina Hasantha
2019-02-03 14:00:34 +01:00
committed by GitHub
parent a75325fb52
commit 16014bb38e
734 changed files with 131230 additions and 17430 deletions

View File

@@ -0,0 +1,7 @@
import {
AttendanceAdapter,
EmployeeAttendanceSheetAdapter,
} from './lib';
window.AttendanceAdapter = AttendanceAdapter;
window.EmployeeAttendanceSheetAdapter = EmployeeAttendanceSheetAdapter;

View File

@@ -0,0 +1,468 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/* global modJs, modJsList */
import AdapterBase from '../../../api/AdapterBase';
import FormValidation from '../../../api/FormValidation';
class AttendanceAdapter extends AdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.punch = null;
this.useServerTime = 0;
this.photoTaken = 0;
this.photoAttendance = 0;
}
updatePunchButton() {
this.getPunch('changePunchButtonSuccessCallBack');
}
setUseServerTime(val) {
this.useServerTime = val;
}
setPhotoAttendance(val) {
this.photoAttendance = parseInt(val, 10);
}
getDataMapping() {
return [
'id',
'in_time',
'out_time',
'note',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Time-In' },
{ sTitle: 'Time-Out' },
{ sTitle: 'Note' },
];
}
getFormFields() {
if (this.useServerTime === 0) {
return [
['id', { label: 'ID', type: 'hidden' }],
['time', { label: 'Time', type: 'datetime' }],
['note', { label: 'Note', type: 'textarea', validation: 'none' }],
];
}
return [
['id', { label: 'ID', type: 'hidden' }],
['note', { label: 'Note', type: 'textarea', validation: 'none' }],
];
}
getCustomTableParams() {
const that = this;
const dataTableParams = {
aoColumnDefs: [
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 1);
},
aTargets: [1],
},
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 2);
},
aTargets: [2],
},
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 3);
},
aTargets: [3],
},
{
fnRender: that.getActionButtons,
aTargets: [that.getDataMapping().length],
},
],
};
return dataTableParams;
}
preProcessRemoteTableData(data, cell, id) {
if (id === 1) {
if (cell === '0000-00-00 00:00:00' || cell === '' || cell === undefined || cell === null) {
return '';
}
return Date.parse(cell).toString('yyyy MMM d <b>HH:mm</b>');
} if (id === 2) {
if (cell === '0000-00-00 00:00:00' || cell === '' || cell === undefined || cell === null) {
return '';
}
return Date.parse(cell).toString('MMM d <b>HH:mm</b>');
} if (id === 3) {
if (cell !== undefined && cell !== null) {
if (cell.length > 20) {
return `${cell.substring(0, 20)}..`;
}
}
return cell;
}
return cell;
}
getActionButtonsHtml(id, data) {
return '';
}
getTableTopButtonHtml() {
if (this.punch === null || this.punch === undefined) {
return '<button id="punchButton" style="float:right;" onclick="modJs.showPunchDialog();return false;" class="btn btn-small">Punch-in <span class="icon-time"></span></button>';
}
return '<button id="punchButton" style="float:right;" onclick="modJs.showPunchDialog();return false;" class="btn btn-small">Punch-out <span class="icon-time"></span></button>';
}
save() {
const that = this;
const validator = new FormValidation(`${this.getTableName()}_submit`, true, { ShowPopup: false, LabelErrorClass: 'error' });
if (validator.checkValues()) {
const msg = this.doCustomValidation();
if (msg == null) {
let params = validator.getFormParameters();
params = this.forceInjectValuesBeforeSave(params);
params.cdate = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' ');
const reqJson = JSON.stringify(params);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'saveSuccessCallback';
callBackData.callBackFail = 'getPunchFailCallBack';
this.customAction('savePunch', 'modules=attendance', reqJson, callBackData, true);
} else {
$(`#${this.getTableName()}Form .label`).html(msg);
$(`#${this.getTableName()}Form .label`).show();
}
}
}
saveSuccessCallback(callBackData) {
this.punch = callBackData;
this.getPunch('changePunchButtonSuccessCallBack');
$('#PunchModel').modal('hide');
this.get([]);
}
cancel() {
$('#PunchModel').modal('hide');
}
showPunchDialog() {
this.getPunch('showPunchDialogShowPunchSuccessCallBack');
}
getPunch(successCallBack) {
const that = this;
const object = {};
object.date = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' ');
object.offset = this.getClientGMTOffset();
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = successCallBack;
callBackData.callBackFail = 'getPunchFailCallBack';
this.customAction('getPunch', 'modules=attendance', reqJson, callBackData);
}
showPunchDialogShowPunchSuccessCallBack(callBackData) {
this.punch = callBackData;
$('#PunchModel').modal('show');
if (this.punch === null) {
$('#PunchModel').find('h3').html('Punch Time-in');
modJs.renderForm();
} else {
$('#PunchModel').find('h3').html('Punch Time-out');
modJs.renderForm(this.punch);
}
$('#Attendance').show();
const picker = $('#time_datetime').data('datetimepicker');
picker.setLocalDate(new Date());
}
changePunchButtonSuccessCallBack(callBackData) {
this.punch = callBackData;
if (this.punch === null) {
$('#punchButton').html('Punch-in <span class="icon-time"></span>');
} else {
$('#punchButton').html('Punch-out <span class="icon-time"></span>');
}
}
getPunchFailCallBack(callBackData) {
this.showMessage('Error Occured while Time Punch', callBackData);
}
getClientDate(date) {
const offset = this.getClientGMTOffset();
const tzDate = date.addMinutes(offset * 60);
return tzDate;
}
getClientGMTOffset() {
const rightNow = new Date();
const jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
const temp = jan1.toGMTString();
const jan2 = new Date(temp.substring(0, temp.lastIndexOf(' ') - 1));
return (jan1 - jan2) / (1000 * 60 * 60);
}
doCustomValidation(params) {
if (this.photoAttendance === 1 && !this.photoTaken) {
return 'Please attach a photo before submitting';
}
return null;
}
forceInjectValuesBeforeSave(params) {
if (this.photoAttendance === 1) {
const canvas = document.getElementById('attendnaceCanvas');
params.image = canvas.toDataURL();
}
return params;
}
postRenderForm() {
if (this.photoAttendance === 1) {
$('.photoAttendance').show();
const video = document.getElementById('attendnaceVideo');
// Get access to the camera!
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
video.src = window.URL.createObjectURL(stream);
video.play();
});
}
this.photoTaken = false;
this.configureEvents();
} else {
$('.photoAttendance').remove();
}
}
configureEvents() {
const that = this;
const canvas = document.getElementById('attendnaceCanvas');
const context = canvas.getContext('2d');
const video = document.getElementById('attendnaceVideo');
$('.attendnaceSnap').click(() => {
context.drawImage(video, 0, 0, 208, 156);
that.photoTaken = true;
return false;
});
}
}
class EmployeeAttendanceSheetAdapter extends AdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.currentTimesheetId = null;
this.currentTimesheet = null;
}
getDataMapping() {
return [
'id',
'date_start',
'date_end',
'total_time',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Start Date' },
{ sTitle: 'End Date' },
{ sTitle: 'Total Time' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['date_start', { label: 'TimeSheet Start Date', type: 'date', validation: '' }],
['date_end', { label: 'TimeSheet End Date', type: 'date', validation: '' }],
['details', { label: 'Reason', type: 'textarea', validation: 'none' }],
];
}
preProcessTableData(row) {
row[1] = Date.parse(row[1]).toString('MMM d, yyyy (dddd)');
row[2] = Date.parse(row[2]).toString('MMM d, yyyy (dddd)');
return row;
}
renderForm(object) {
const formHtml = this.templates.formTemplate;
const html = '';
$(`#${this.getTableName()}Form`).html(formHtml);
$(`#${this.getTableName()}Form`).show();
$(`#${this.getTableName()}`).hide();
$('#attendnacesheet_start').html(Date.parse(object.date_start).toString('MMM d, yyyy (dddd)'));
$('#attendnacesheet_end').html(Date.parse(object.date_end).toString('MMM d, yyyy (dddd)'));
this.currentTimesheet = object;
this.getTimeEntries();
}
getTimeEntries() {
const timesheetId = this.currentId;
const sourceMappingJson = JSON.stringify(modJsList.tabEmployeeTimeEntry.getSourceMapping());
const reqJson = JSON.stringify({ id: timesheetId, sm: sourceMappingJson });
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'getTimeEntriesSuccessCallBack';
callBackData.callBackFail = 'getTimeEntriesFailCallBack';
this.customAction('getTimeEntries', 'modules=time_sheets', reqJson, callBackData);
}
getTimeEntriesSuccessCallBack(callBackData) {
const entries = callBackData;
let html = '';
const temp = '<tr><td><img class="tableActionButton" src="_BASE_images/delete.png" style="cursor:pointer;" rel="tooltip" title="Delete" onclick="modJsList[\'tabEmployeeTimeEntry\'].deleteRow(_id_);return false;"></img></td><td>_start_</td><td>_end_</td><td>_duration_</td><td>_project_</td><td>_details_</td>';
for (let i = 0; i < entries.length; i++) {
try {
let t = temp;
t = t.replace(/_start_/g, Date.parse(entries[i].date_start).toString('MMM d, yyyy [hh:mm tt]'));
t = t.replace(/_end_/g, Date.parse(entries[i].date_end).toString('MMM d, yyyy [hh:mm tt]'));
const mili = Date.parse(entries[i].date_end) - Date.parse(entries[i].date_start);
const minutes = Math.round(mili / 60000);
const hourMinutes = (minutes % 60);
const hours = (minutes - hourMinutes) / 60;
t = t.replace(/_duration_/g, `Hours (${hours}) - Min (${hourMinutes})`);
if (entries[i].project === 'null' || entries[i].project === null || entries[i].project === undefined) {
t = t.replace(/_project_/g, 'None');
} else {
t = t.replace(/_project_/g, entries[i].project);
}
t = t.replace(/_project_/g, entries[i].project);
t = t.replace(/_details_/g, entries[i].details);
t = t.replace(/_id_/g, entries[i].id);
t = t.replace(/_BASE_/g, this.baseUrl);
html += t;
} catch (e) {
// DN
}
}
$('.timesheet_entries_table_body').html(html);
if (modJs.getTableName() === 'SubEmployeeTimeSheetAll') {
$('#submit_sheet').hide();
$('#add_time_sheet_entry').hide();
} else if (this.currentElement.status === 'Approved') {
$('#submit_sheet').hide();
$('#add_time_sheet_entry').hide();
} else {
$('#submit_sheet').show();
$('#add_time_sheet_entry').show();
}
}
getTimeEntriesFailCallBack(callBackData) {
this.showMessage('Error', 'Error occured while getting timesheet entries');
}
createPreviousAttendnacesheet(id) {
const reqJson = JSON.stringify({ id });
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'createPreviousAttendnacesheetSuccessCallBack';
callBackData.callBackFail = 'createPreviousAttendnacesheetFailCallBack';
this.customAction('createPreviousAttendnaceSheet', 'modules=attendnace', reqJson, callBackData);
}
createPreviousAttendnacesheetSuccessCallBack(callBackData) {
$('.tooltip').css('display', 'none');
$('.tooltip').remove();
// this.showMessage("Success", "Previous Timesheet created");
this.get([]);
}
createPreviousAttendnacesheetFailCallBack(callBackData) {
this.showMessage('Error', callBackData);
}
getActionButtonsHtml(id, data) {
let html = '';
if (this.getTableName() === 'EmployeeTimeSheetAll') {
html = '<div style="width:80px;"><img class="tableActionButton" src="_BASE_images/view.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img><img class="tableActionButton" src="_BASE_images/redo.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Create previous time sheet" onclick="modJs.createPreviousAttendnacesheet(_id_);return false;"></img></div>';
} else {
html = '<div style="width:80px;"><img class="tableActionButton" src="_BASE_images/view.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img></div>';
}
html = html.replace(/_id_/g, id);
html = html.replace(/_BASE_/g, this.baseUrl);
return html;
}
getCustomTableParams() {
const that = this;
const dataTableParams = {
aoColumnDefs: [
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 1);
},
aTargets: [1],
},
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 2);
},
aTargets: [2],
},
{
fnRender: that.getActionButtons,
aTargets: [that.getDataMapping().length],
},
],
};
return dataTableParams;
}
preProcessRemoteTableData(data, cell, id) {
return Date.parse(cell).toString('MMM d, yyyy (dddd)');
}
}
module.exports = {
AttendanceAdapter,
EmployeeAttendanceSheetAdapter,
};

View File

@@ -0,0 +1,3 @@
import { DashboardAdapter } from './lib';
window.DashboardAdapter = DashboardAdapter;

View File

@@ -0,0 +1,99 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
class DashboardAdapter extends AdapterBase {
getDataMapping() {
return [];
}
getHeaders() {
return [];
}
getFormFields() {
return [];
}
get(callBackData) {
}
getPunch() {
const that = this;
const object = {};
object.date = this.getClientDate(new Date()).toISOString().slice(0, 19).replace('T', ' ');
object.offset = this.getClientGMTOffset();
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'getPunchSuccessCallBack';
callBackData.callBackFail = 'getPunchFailCallBack';
this.customAction('getPunch', 'modules=attendance', reqJson, callBackData);
}
getPunchSuccessCallBack(callBackData) {
const punch = callBackData;
if (punch == null) {
$('#lastPunchTime').html('Not');
$('#punchTimeText').html('Punched In');
} else {
$('#lastPunchTime').html(Date.parse(punch.in_time).toString('h:mm tt'));
$('#punchTimeText').html('Punched In');
}
}
getPunchFailCallBack(callBackData) {
}
getInitData() {
const that = this;
const object = {};
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'getInitDataSuccessCallBack';
callBackData.callBackFail = 'getInitDataFailCallBack';
this.customAction('getInitData', 'modules=dashboard', reqJson, callBackData);
}
getInitDataSuccessCallBack(data) {
$('#timeSheetHoursWorked').html(data.lastTimeSheetHours);
$('#numberOfProjects').html(data.activeProjects);
$('#pendingLeaveCount').html(data.pendingLeaves);
$('#numberOfEmployees').html(`${data.numberOfEmployees} Subordinates`);
$('#numberOfCandidates').html(`${data.numberOfCandidates} Candidates`);
$('#numberOfJobs').html(`${data.numberOfJobs} Active`);
$('#numberOfCourses').html(`${data.numberOfCourses} Active`);
}
getInitDataFailCallBack(callBackData) {
}
getClientDate(date) {
const offset = this.getClientGMTOffset();
const tzDate = date.addMinutes(offset * 60);
return tzDate;
}
getClientGMTOffset() {
const rightNow = new Date();
const jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
const temp = jan1.toGMTString();
const jan2 = new Date(temp.substring(0, temp.lastIndexOf(' ') - 1));
return (jan1 - jan2) / (1000 * 60 * 60);
}
}
module.exports = { DashboardAdapter };

View File

@@ -0,0 +1,3 @@
import { EmployeeDependentAdapter } from './lib';
window.EmployeeDependentAdapter = EmployeeDependentAdapter;

View File

@@ -0,0 +1,44 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
/**
* EmployeeDependentAdapter
*/
class EmployeeDependentAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'name',
'relationship',
'dob',
'id_number',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
{ sTitle: 'Relationship' },
{ sTitle: 'Date of Birth' },
{ sTitle: 'Id Number' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['name', { label: 'Name', type: 'text', validation: '' }],
['relationship', { label: 'Relationship', type: 'select', source: [['Child', 'Child'], ['Spouse', 'Spouse'], ['Parent', 'Parent'], ['Other', 'Other']] }],
['dob', { label: 'Date of Birth', type: 'date', validation: '' }],
['id_number', { label: 'Id Number', type: 'text', validation: 'none' }],
];
}
}
module.exports = { EmployeeDependentAdapter };

View File

@@ -0,0 +1,3 @@
import { EmergencyContactAdapter } from './lib';
window.EmergencyContactAdapter = EmergencyContactAdapter;

View File

@@ -0,0 +1,44 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
class EmergencyContactAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'name',
'relationship',
'home_phone',
'work_phone',
'mobile_phone',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
{ sTitle: 'Relationship' },
{ sTitle: 'Home Phone' },
{ sTitle: 'Work Phone' },
{ sTitle: 'Mobile Phone' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['name', { label: 'Name', type: 'text', validation: '' }],
['relationship', { label: 'Relationship', type: 'text', validation: 'none' }],
['home_phone', { label: 'Home Phone', type: 'text', validation: 'none' }],
['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }],
['mobile_phone', { label: 'Mobile Phone', type: 'text', validation: 'none' }],
];
}
}
module.exports = { EmergencyContactAdapter };

View File

@@ -0,0 +1,9 @@
import {
EmployeeAdapter,
CompanyGraphAdapter,
ApiAccessAdapter,
} from './lib';
window.EmployeeAdapter = EmployeeAdapter;
window.CompanyGraphAdapter = CompanyGraphAdapter;
window.ApiAccessAdapter = ApiAccessAdapter;

View File

@@ -0,0 +1,724 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/* eslint-disable camelcase,no-underscore-dangle */
/* global d3 */
import QRCode from 'qrcode';
import AdapterBase from '../../../api/AdapterBase';
class EmployeeAdapter extends AdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.fieldNameMap = {};
this.hiddenFields = {};
this.tableFields = {};
this.formOnlyFields = {};
this.currentUserId = null;
}
setFieldNameMap(fields) {
let field;
for (let i = 0; i < fields.length; i++) {
field = fields[i];
this.fieldNameMap[field.name] = field;
if (field.display === 'Hidden') {
this.hiddenFields[field.name] = field;
} else if (field.display === 'Table and Form') {
this.tableFields[field.name] = field;
} else {
this.formOnlyFields[field.name] = field;
}
}
}
getDataMapping() {
return [
'id',
'employee_id',
'first_name',
'last_name',
'mobile_phone',
'department',
'gender',
'supervisor',
];
}
getHeaders() {
return [
{ sTitle: 'ID' },
{ sTitle: 'Employee Number' },
{ sTitle: 'First Name' },
{ sTitle: 'Last Name' },
{ sTitle: 'Mobile' },
{ sTitle: 'Department' },
{ sTitle: 'Gender' },
{ sTitle: 'Supervisor' },
];
}
getFormFields() {
const newFields = [];
let employee_id; let ssn_num; let employment_status; let job_title; let pay_grade; let joined_date; let department; let work_email; let
country;
if (this.checkPermission('Edit Employee Number') === 'Yes') {
employee_id = ['employee_id', { label: 'Employee Number', type: 'text', validation: '' }];
} else {
employee_id = ['employee_id', { label: 'Employee Number', type: 'placeholder', validation: '' }];
}
if (this.checkPermission('Edit EPF/CPF Number') === 'Yes') {
ssn_num = ['ssn_num', { label: 'EPF/CPF/SS No', type: 'text', validation: 'none' }];
} else {
ssn_num = ['ssn_num', { label: 'EPF/CPF/SS No', type: 'placeholder', validation: 'none' }];
}
if (this.checkPermission('Edit Employment Status') === 'Yes') {
employment_status = ['employment_status', { label: 'Employment Status', type: 'select2', 'remote-source': ['EmploymentStatus', 'id', 'name'] }];
} else {
employment_status = ['employment_status', { label: 'Employment Status', type: 'placeholder', 'remote-source': ['EmploymentStatus', 'id', 'name'] }];
}
if (this.checkPermission('Edit Job Title') === 'Yes') {
job_title = ['job_title', { label: 'Job Title', type: 'select2', 'remote-source': ['JobTitle', 'id', 'name'] }];
} else {
job_title = ['job_title', { label: 'Job Title', type: 'placeholder', 'remote-source': ['JobTitle', 'id', 'name'] }];
}
if (this.checkPermission('Edit Pay Grade') === 'Yes') {
pay_grade = ['pay_grade', {
label: 'Pay Grade', type: 'select2', 'allow-null': true, 'remote-source': ['PayGrade', 'id', 'name'],
}];
} else {
pay_grade = ['pay_grade', {
label: 'Pay Grade', type: 'placeholder', 'allow-null': true, 'remote-source': ['PayGrade', 'id', 'name'],
}];
}
if (this.checkPermission('Edit Joined Date') === 'Yes') {
joined_date = ['joined_date', { label: 'Joined Date', type: 'date', validation: '' }];
} else {
joined_date = ['joined_date', { label: 'Joined Date', type: 'placeholder', validation: '' }];
}
if (this.checkPermission('Edit Department') === 'Yes') {
department = ['department', { label: 'Department', type: 'select2', 'remote-source': ['CompanyStructure', 'id', 'title'] }];
} else {
department = ['department', { label: 'Department', type: 'placeholder', 'remote-source': ['CompanyStructure', 'id', 'title'] }];
}
if (this.checkPermission('Edit Work Email') === 'Yes') {
work_email = ['work_email', { label: 'Work Email', type: 'text', validation: 'email' }];
} else {
work_email = ['work_email', { label: 'Work Email', type: 'placeholder', validation: 'emailOrEmpty' }];
}
if (this.checkPermission('Edit Country') === 'Yes') {
country = ['country', { label: 'Country', type: 'select2', 'remote-source': ['Country', 'code', 'name'] }];
} else {
country = ['country', { label: 'Country', type: 'placeholder', 'remote-source': ['Country', 'code', 'name'] }];
}
const fields = [
['id', { label: 'ID', type: 'hidden', validation: '' }],
employee_id,
['first_name', { label: 'First Name', type: 'text', validation: '' }],
['middle_name', { label: 'Middle Name', type: 'text', validation: 'none' }],
['last_name', { label: 'Last Name', type: 'text', validation: '' }],
['nationality', { label: 'Nationality', type: 'select2', 'remote-source': ['Nationality', 'id', 'name'] }],
['birthday', { label: 'Date of Birth', type: 'date', validation: '' }],
['gender', { label: 'Gender', type: 'select', source: [['Male', 'Male'], ['Female', 'Female']] }],
['marital_status', { label: 'Marital Status', type: 'select', source: [['Married', 'Married'], ['Single', 'Single'], ['Divorced', 'Divorced'], ['Widowed', 'Widowed'], ['Other', 'Other']] }],
ssn_num,
['nic_num', { label: 'NIC', type: 'text', validation: 'none' }],
['other_id', { label: 'Other ID', type: 'text', validation: 'none' }],
['driving_license', { label: 'Driving License No', type: 'text', validation: 'none' }],
employment_status,
job_title,
pay_grade,
['work_station_id', { label: 'Work Station Id', type: 'text', validation: 'none' }],
['address1', { label: 'Address Line 1', type: 'text', validation: 'none' }],
['address2', { label: 'Address Line 2', type: 'text', validation: 'none' }],
['city', { label: 'City', type: 'text', validation: 'none' }],
country,
['province', {
label: 'Province', type: 'select2', 'allow-null': true, 'remote-source': ['Province', 'id', 'name'],
}],
['postal_code', { label: 'Postal/Zip Code', type: 'text', validation: 'none' }],
['home_phone', { label: 'Home Phone', type: 'text', validation: 'none' }],
['mobile_phone', { label: 'Mobile Phone', type: 'text', validation: 'none' }],
['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }],
work_email,
['private_email', { label: 'Private Email', type: 'text', validation: 'emailOrEmpty' }],
joined_date,
department,
];
for (let i = 0; i < this.customFields.length; i++) {
fields.push(this.customFields[i]);
}
for (let i = 0; i < fields.length; i++) {
const tempField = fields[i];
if (this.hiddenFields[tempField[0]] === undefined || this.hiddenFields[tempField[0]] === null) {
if (this.fieldNameMap[tempField[0]] !== undefined && this.fieldNameMap[tempField[0]] !== null) {
const title = this.fieldNameMap[tempField[0]].textMapped;
tempField[1].label = title;
}
newFields.push(tempField);
}
}
return newFields;
}
getSourceMapping() {
const k = this.sourceMapping;
k.supervisor = ['Employee', 'id', 'first_name+last_name'];
return k;
}
get() {
const sourceMappingJson = JSON.stringify(this.getSourceMapping());
const req = { map: sourceMappingJson };
const reqJson = JSON.stringify(req);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'modEmployeeGetSuccessCallBack';
callBackData.callBackFail = 'modEmployeeGetFailCallBack';
this.customAction('get', 'modules=employees', reqJson, callBackData);
}
deleteProfileImage(empId) {
const req = { id: empId };
const reqJson = JSON.stringify(req);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'modEmployeeDeleteProfileImageCallBack';
callBackData.callBackFail = 'modEmployeeDeleteProfileImageCallBack';
this.customAction('deleteProfileImage', 'modules=employees', reqJson, callBackData);
}
modEmployeeDeleteProfileImageCallBack(data) {
// eslint-disable-next-line no-restricted-globals
top.location.href = top.location.href;
}
modEmployeeGetSuccessCallBack(data) {
const fields = this.getFormFields();
const currentEmpId = data[1];
const userEmpId = data[2];
[data] = data;
let html = this.getCustomTemplate('myDetails.html');
for (let i = 0; i < fields.length; i++) {
if (this.fieldNameMap[fields[i][0]] !== undefined && this.fieldNameMap[fields[i][0]] !== null) {
const title = this.fieldNameMap[fields[i][0]].textMapped;
html = html.replace(`#_label_${fields[i][0]}_#`, this.gt(title));
}
}
html = html.replace(/#_.+_#/gi, '');
html = html.replace(/_id_/g, data.id);
$(`#${this.getTableName()}`).html(html);
for (let i = 0; i < fields.length; i++) {
$(`#${this.getTableName()} #${fields[i][0]}`).html(data[fields[i][0]]);
$(`#${this.getTableName()} #${fields[i][0]}_Name`).html(data[`${fields[i][0]}_Name`]);
}
$(`#${this.getTableName()} #supervisor_Name`).html(data.supervisor_Name);
let subordinates = '';
for (let i = 0; i < data.subordinates.length; i++) {
if (data.subordinates[i].first_name !== undefined && data.subordinates[i].first_name !== null) {
subordinates += `${data.subordinates[i].first_name} `;
}
if (data.subordinates[i].middle_name !== undefined && data.subordinates[i].middle_name !== null && data.subordinates[i].middle_name !== '') {
subordinates += `${data.subordinates[i].middle_name} `;
}
if (data.subordinates[i].last_name !== undefined && data.subordinates[i].last_name !== null && data.subordinates[i].last_name !== '') {
subordinates += data.subordinates[i].last_name;
}
subordinates += '<br/>';
}
// Add custom fields
if (data.customFields !== undefined && data.customFields !== null && Object.keys(data.customFields).length > 0) {
const ct = '<div class="col-xs-6 col-md-3" style="font-size:16px;"><label class="control-label col-xs-12" style="font-size:13px;">#_label_#</label><label class="control-label col-xs-12 iceLabel" style="font-size:13px;font-weight: bold;">#_value_#</label></div>';
const sectionTemplate = '<div class="panel panel-default" style="width:97.5%;"><div class="panel-heading"><h4>#_section.name_#</h4></div> <div class="panel-body" id="cont_#_section_#"> </div></div>';
let customFieldHtml;
for (const index in data.customFields) {
if (!data.customFields[index][1]) {
data.customFields[index][1] = this.gt('Other Details');
}
let sectionId = data.customFields[index][1].toLocaleLowerCase();
sectionId = sectionId.replace(' ', '_');
if ($(`#cont_${sectionId}`).length <= 0) {
// Add section
let sectionHtml = sectionTemplate;
sectionHtml = sectionHtml.replace('#_section_#', sectionId);
sectionHtml = sectionHtml.replace('#_section.name_#', data.customFields[index][1]);
$('#customFieldsCont').append($(sectionHtml));
}
customFieldHtml = ct;
customFieldHtml = customFieldHtml.replace('#_label_#', index);
if (data.customFields[index][2] === 'fileupload') {
customFieldHtml = customFieldHtml.replace(
'#_value_#',
`<button onclick="download('${data.customFields[index][0]}');return false;" class="btn btn-mini btn-inverse" type="button">View: ${index}</button>`,
);
} else {
customFieldHtml = customFieldHtml.replace('#_value_#', data.customFields[index][0]);
}
$(`#cont_${sectionId}`).append($(customFieldHtml));
}
} else {
$('#customFieldsCont').remove();
}
$(`#${this.getTableName()} #subordinates`).html(subordinates);
$(`#${this.getTableName()} #name`).html(`${data.first_name} ${data.last_name}`);
this.currentUserId = data.id;
$(`#${this.getTableName()} #profile_image_${data.id}`).attr('src', data.image);
if (this.checkPermission('Upload/Delete Profile Image') === 'No') {
$('#employeeUploadProfileImage').remove();
$('#employeeDeleteProfileImage').remove();
}
if (this.checkPermission('Edit Employee Details') === 'No') {
$('#employeeProfileEditInfo').remove();
}
if (currentEmpId !== userEmpId) {
$('#employeeUpdatePassword').remove();
}
this.cancel();
}
modEmployeeGetFailCallBack(data) {
}
editEmployee() {
this.edit(this.currentUserId);
}
changePassword() {
$('#adminUsersModel').modal('show');
$('#adminUsersChangePwd #newpwd').val('');
$('#adminUsersChangePwd #conpwd').val('');
}
changePasswordConfirm() {
$('#adminUsersChangePwd_error').hide();
const passwordValidation = function (str) {
return str.length > 7;
};
const password = $('#adminUsersChangePwd #newpwd').val();
if (!passwordValidation(password)) {
$('#adminUsersChangePwd_error').html('Password should be longer than 7 characters');
$('#adminUsersChangePwd_error').show();
return;
}
const conPassword = $('#adminUsersChangePwd #conpwd').val();
if (conPassword !== password) {
$('#adminUsersChangePwd_error').html("Passwords don't match");
$('#adminUsersChangePwd_error').show();
return;
}
const req = { pwd: conPassword };
const reqJson = JSON.stringify(req);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'changePasswordSuccessCallBack';
callBackData.callBackFail = 'changePasswordFailCallBack';
this.customAction('changePassword', 'modules=employees', reqJson, callBackData);
}
closeChangePassword() {
$('#adminUsersModel').modal('hide');
}
changePasswordSuccessCallBack(callBackData, serverData) {
this.closeChangePassword();
this.showMessage('Password Change', 'Password changed successfully');
}
changePasswordFailCallBack(callBackData, serverData) {
this.closeChangePassword();
this.showMessage('Error', callBackData);
}
}
/*
* Company Graph
*/
class CompanyStructureAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'title',
'address',
'type',
'country',
'parent',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Name' },
{ sTitle: 'Address' },
{ sTitle: 'Type' },
{ sTitle: 'Country', sClass: 'center' },
{ sTitle: 'Parent Structure' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden', validation: '' }],
['title', { label: 'Name', type: 'text', validation: '' }],
['description', { label: 'Details', type: 'textarea', validation: '' }],
['address', { label: 'Address', type: 'textarea', validation: 'none' }],
['type', { label: 'Type', type: 'select', source: [['Company', 'Company'], ['Head Office', 'Head Office'], ['Regional Office', 'Regional Office'], ['Department', 'Department'], ['Unit', 'Unit'], ['Sub Unit', 'Sub Unit'], ['Other', 'Other']] }],
['country', { label: 'Country', type: 'select', 'remote-source': ['Country', 'code', 'name'] }],
['parent', {
label: 'Parent Structure', type: 'select', 'allow-null': true, 'remote-source': ['CompanyStructure', 'id', 'title'],
}],
];
}
}
class CompanyGraphAdapter extends CompanyStructureAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.nodeIdCounter = 0;
}
convertToTree(data) {
const ice = {};
ice.id = -1;
ice.title = '';
ice.name = '';
ice.children = [];
let parent = null;
const added = {};
for (let i = 0; i < data.length; i++) {
data[i].name = data[i].title;
if (data[i].parent !== null && data[i].parent !== undefined) {
parent = this.findParent(data, data[i].parent);
if (parent !== null) {
if (parent.children === undefined || parent.children === null) {
parent.children = [];
}
parent.children.push(data[i]);
}
}
}
for (let i = 0; i < data.length; i++) {
if (data[i].parent === null || data[i].parent === undefined) {
ice.children.push(data[i]);
}
}
return ice;
}
findParent(data, parent) {
for (let i = 0; i < data.length; i++) {
if (data[i].title === parent || data[i].title === parent) {
return data[i];
}
}
return null;
}
createTable(elementId) {
$('#tabPageCompanyGraph').html('');
const that = this;
// eslint-disable-next-line prefer-destructuring
const sourceData = this.sourceData;
// this.fixCyclicParent(sourceData);
const treeData = this.convertToTree(sourceData);
const m = [20, 120, 20, 120];
const w = 5000 - m[1] - m[3];
const h = 1000 - m[0] - m[2];
const tree = d3.layout.tree()
.size([h, w]);
this.diagonal = d3.svg.diagonal()
.projection(d => [d.y, d.x]);
this.vis = d3.select('#tabPageCompanyGraph').append('svg:svg')
.attr('width', w + m[1] + m[3])
.attr('height', h + m[0] + m[2])
.append('svg:g')
.attr('transform', `translate(${m[3]},${m[0]})`);
const root = treeData;
root.x0 = h / 2;
root.y0 = 0;
function toggleAll(d) {
if (d.children) {
console.log(d.name);
d.children.forEach(toggleAll);
that.toggle(d);
}
}
this.update(root, tree, root);
}
update(source, tree, root) {
const that = this;
const duration = d3.event && d3.event.altKey ? 5000 : 500;
// Compute the new tree layout.
const nodes = tree.nodes(root).reverse();
// Normalize for fixed-depth.
nodes.forEach((d) => { d.y = d.depth * 180; });
// Update the nodes<65>
const node = that.vis.selectAll('g.node')
// eslint-disable-next-line no-return-assign
.data(nodes, d => d.id || (d.id = ++that.nodeIdCounter));
// Enter any new nodes at the parent's previous position.
const nodeEnter = node.enter().append('svg:g')
.attr('class', 'node')
.attr('transform', d => `translate(${source.y0},${source.x0})`)
.on('click', (d) => { that.toggle(d); that.update(d, tree, root); });
nodeEnter.append('svg:circle')
.attr('r', 1e-6)
// eslint-disable-next-line no-underscore-dangle
.style('fill', d => (d._children ? 'lightsteelblue' : '#fff'));
nodeEnter.append('svg:text')
.attr('x', d => (d.children || d._children ? -10 : 10))
.attr('dy', '.35em')
.attr('text-anchor', d => (d.children || d._children ? 'end' : 'start'))
.text(d => d.name)
.style('fill-opacity', 1e-6);
// Transition nodes to their new position.
const nodeUpdate = node.transition()
.duration(duration)
.attr('transform', d => `translate(${d.y},${d.x})`);
nodeUpdate.select('circle')
.attr('r', 4.5)
.style('fill', d => (d._children ? 'lightsteelblue' : '#fff'));
nodeUpdate.select('text')
.style('fill-opacity', 1);
// Transition exiting nodes to the parent's new position.
const nodeExit = node.exit().transition()
.duration(duration)
.attr('transform', d => `translate(${source.y},${source.x})`)
.remove();
nodeExit.select('circle')
.attr('r', 1e-6);
nodeExit.select('text')
.style('fill-opacity', 1e-6);
// Update the links<6B>
const link = that.vis.selectAll('path.link')
.data(tree.links(nodes), d => d.target.id);
// Enter any new links at the parent's previous position.
link.enter().insert('svg:path', 'g')
.attr('class', 'link')
.attr('d', (d) => {
const o = { x: source.x0, y: source.y0 };
return that.diagonal({ source: o, target: o });
})
.transition()
.duration(duration)
.attr('d', that.diagonal);
// Transition links to their new position.
link.transition()
.duration(duration)
.attr('d', that.diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr('d', (d) => {
const o = { x: source.x, y: source.y };
return that.diagonal({ source: o, target: o });
})
.remove();
// Stash the old positions for transition.
nodes.forEach((d) => {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children.
toggle(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
}
getSourceDataById(id) {
for (let i = 0; i < this.sourceData.length; i++) {
if (this.sourceData[i].id === id) {
return this.sourceData[i];
}
}
return null;
}
fixCyclicParent(sourceData) {
let errorMsg = '';
for (let i = 0; i < sourceData.length; i++) {
const obj = sourceData[i];
let curObj = obj;
const parentIdArr = {};
parentIdArr[curObj.id] = 1;
while (curObj.parent != null && curObj.parent !== undefined) {
const parent = this.getSourceDataById(curObj.parent);
if (parent == null) {
break;
} else if (parentIdArr[parent.id] === 1) {
errorMsg = `${obj.title}'s parent structure set to ${parent.title}<br/>`;
obj.parent = null;
break;
}
parentIdArr[parent.id] = 1;
curObj = parent;
}
}
if (errorMsg !== '') {
this.showMessage('Company Structure is having a cyclic dependency', `We found a cyclic dependency due to following reasons:<br/>${errorMsg}`);
return false;
}
return true;
}
}
/*
* Api Access
*/
class ApiAccessAdapter extends AdapterBase {
getDataMapping() {
return [
];
}
getHeaders() {
return [
];
}
getFormFields() {
return [
];
}
setApiUrl(apiUrl) {
this.apiUrl = apiUrl;``
}
setToken(token) {
this.token = token;
}
get() {
const canvas = document.getElementById('apiQRcode');
QRCode.toCanvas(canvas, JSON.stringify({
key: 'IceHrm',
url: this.apiUrl,
token: this.token,
}), (error) => {
if (error) {
console.log(error);
}
});
}
}
module.exports = {
EmployeeAdapter,
CompanyGraphAdapter,
ApiAccessAdapter,
};

View File

@@ -0,0 +1,5 @@
import {
EmployeeCompanyLoanAdapter,
} from './lib';
window.EmployeeCompanyLoanAdapter = EmployeeCompanyLoanAdapter;

View File

@@ -0,0 +1,89 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
class EmployeeCompanyLoanAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'loan',
'start_date',
'period_months',
'currency',
'amount',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Loan Type' },
{ sTitle: 'Loan Start Date' },
{ sTitle: 'Loan Period (Months)' },
{ sTitle: 'Currency' },
{ sTitle: 'Amount' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['loan', { label: 'Loan Type', type: 'placeholder', 'remote-source': ['CompanyLoan', 'id', 'name'] }],
['start_date', { label: 'Loan Start Date', type: 'placeholder', validation: '' }],
['last_installment_date', { label: 'Last Installment Date', type: 'placeholder', validation: 'none' }],
['period_months', { label: 'Loan Period (Months)', type: 'placeholder', validation: 'number' }],
['currency', { label: 'Currency', type: 'placeholder', 'remote-source': ['CurrencyType', 'id', 'name'] }],
['amount', { label: 'Loan Amount', type: 'placeholder', validation: 'float' }],
['monthly_installment', { label: 'Monthly Installment', type: 'placeholder', validation: 'float' }],
['status',
{
label: 'Status',
type: 'placeholder',
source: [['Approved', 'Approved'], ['Paid', 'Paid'], ['Suspended', 'Suspended']],
},
],
['details', { label: 'Details', type: 'placeholder', validation: 'none' }],
];
}
// eslint-disable-next-line no-unused-vars
getActionButtonsHtml(id, data) {
const editButton = '<img class="tableActionButton" '
+ 'src="_BASE_images/view.png" '
+ 'style="cursor:pointer;" '
+ 'rel="tooltip" title="View" '
+ 'onclick="modJs.edit(_id_);return false;">'
+ '</img>';
const deleteButton = '<img class="tableActionButton" '
+ 'src="_BASE_images/delete.png" '
+ 'style="margin-left:15px;cursor:pointer;" '
+ 'rel="tooltip" title="Delete" '
+ 'onclick="modJs.deleteRow(_id_);return false;">'
+ '</img>';
let html = '<div style="width:80px;">_edit__delete_</div>';
if (this.showDelete) {
html = html.replace('_delete_', deleteButton);
} else {
html = html.replace('_delete_', '');
}
if (this.showEdit) {
html = html.replace('_edit_', editButton);
} else {
html = html.replace('_edit_', '');
}
html = html.replace(/_id_/g, id);
html = html.replace(/_BASE_/g, this.baseUrl);
return html;
}
}
module.exports = { EmployeeCompanyLoanAdapter };

View File

@@ -0,0 +1,9 @@
import {
EmployeeOvertimeAdapter,
EmployeeOvertimeApproverAdapter,
SubordinateEmployeeOvertimeAdapter,
} from './lib';
window.EmployeeOvertimeAdapter = EmployeeOvertimeAdapter;
window.EmployeeOvertimeApproverAdapter = EmployeeOvertimeApproverAdapter;
window.SubordinateEmployeeOvertimeAdapter = SubordinateEmployeeOvertimeAdapter;

View File

@@ -0,0 +1,134 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import ApproveModuleAdapter from '../../../api/ApproveModuleAdapter';
import {
EmployeeOvertimeAdminAdapter,
} from '../../../admin/src/overtime/lib';
class EmployeeOvertimeAdapter extends ApproveModuleAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.itemName = 'Overtime';
this.itemNameLower = 'employeeovertime';
this.modulePathName = 'overtime';
}
getDataMapping() {
return [
'id',
'category',
'start_time',
'end_time',
'project',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Category' },
{ sTitle: 'Start Time' },
{ sTitle: 'End Time' },
{ sTitle: 'Project' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['category', {
label: 'Category', type: 'select2', 'allow-null': false, 'remote-source': ['OvertimeCategory', 'id', 'name'],
}],
['start_time', { label: 'Start Time', type: 'datetime', validation: '' }],
['end_time', { label: 'End Time', type: 'datetime', validation: '' }],
['project', {
label: 'Project',
type: 'select2',
'allow-null': true,
'null=label': 'none',
'remote-source': ['Project', 'id', 'name'],
}],
['notes', { label: 'Notes', type: 'textarea', validation: 'none' }],
];
}
}
/*
EmployeeOvertimeApproverAdapter
*/
class EmployeeOvertimeApproverAdapter extends EmployeeOvertimeAdminAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.itemName = 'Overtime';
this.itemNameLower = 'employeeovertime';
this.modulePathName = 'overtime';
}
getActionButtonsHtml(id, data) {
const statusChangeButton = '<img class="tableActionButton" src="_BASE_images/run.png" style="cursor:pointer;" '
+ 'rel="tooltip" title="Change Status" onclick="modJs.openStatus(_id_, \'_cstatus_\');return false;">'
+ '</img>';
const viewLogsButton = '<img class="tableActionButton" src="_BASE_images/log.png" '
+ 'style="margin-left:15px;cursor:pointer;" rel="tooltip" title="View Logs" '
+ 'onclick="modJs.getLogs(_id_);return false;"></img>';
let html = '<div style="width:80px;">_status__logs_</div>';
html = html.replace('_logs_', viewLogsButton);
if (data[this.getStatusFieldPosition()] === 'Processing') {
html = html.replace('_status_', statusChangeButton);
} else {
html = html.replace('_status_', '');
}
html = html.replace(/_id_/g, id);
html = html.replace(/_BASE_/g, this.baseUrl);
html = html.replace(/_cstatus_/g, data[this.getStatusFieldPosition()]);
return html;
}
getStatusOptionsData(currentStatus) {
const data = {};
if (currentStatus === 'Processing') {
data.Approved = 'Approved';
data.Rejected = 'Rejected';
}
return data;
}
getStatusOptions(currentStatus) {
return this.generateOptions(this.getStatusOptionsData(currentStatus));
}
}
/*
EmployeeOvertimeAdapter
*/
class SubordinateEmployeeOvertimeAdapter extends EmployeeOvertimeAdminAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.itemName = 'Overtime';
this.itemNameLower = 'employeeovertime';
this.modulePathName = 'overtime';
}
}
module.exports = {
EmployeeOvertimeAdapter,
EmployeeOvertimeApproverAdapter,
SubordinateEmployeeOvertimeAdapter,
};

View File

@@ -0,0 +1,5 @@
import {
EmployeeProjectAdapter,
} from './lib';
window.EmployeeProjectAdapter = EmployeeProjectAdapter;

View File

@@ -0,0 +1,32 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
class EmployeeProjectAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'project',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Project' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['project', { label: 'Project', type: 'select2', 'remote-source': ['Project', 'id', 'name'] }],
['details', { label: 'Details', type: 'textarea', validation: 'none' }],
];
}
}
module.exports = { EmployeeProjectAdapter };

View File

@@ -0,0 +1,11 @@
import {
EmployeeSkillAdapter,
EmployeeEducationAdapter,
EmployeeCertificationAdapter,
EmployeeLanguageAdapter,
} from './lib';
window.EmployeeSkillAdapter = EmployeeSkillAdapter;
window.EmployeeEducationAdapter = EmployeeEducationAdapter;
window.EmployeeCertificationAdapter = EmployeeCertificationAdapter;
window.EmployeeLanguageAdapter = EmployeeLanguageAdapter;

View File

@@ -0,0 +1,160 @@
import AdapterBase from '../../../api/AdapterBase';
class EmployeeSkillAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'skill_id',
'details',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Skill' },
{ sTitle: 'Details' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['skill_id', {
label: 'Skill', type: 'select2', 'allow-null': true, 'remote-source': ['Skill', 'id', 'name'],
}],
['details', { label: 'Details', type: 'textarea', validation: '' }],
];
}
}
/**
* EmployeeEducationAdapter
*/
class EmployeeEducationAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'education_id',
'institute',
'date_start',
'date_end',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Qualification' },
{ sTitle: 'Institute' },
{ sTitle: 'Start Date' },
{ sTitle: 'Completed On' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['education_id', {
label: 'Qualification', type: 'select2', 'allow-null': false, 'remote-source': ['Education', 'id', 'name'],
}],
['institute', { label: 'Institute', type: 'text', validation: '' }],
['date_start', { label: 'Start Date', type: 'date', validation: 'none' }],
['date_end', { label: 'Completed On', type: 'date', validation: 'none' }],
];
}
}
/**
* EmployeeCertificationAdapter
*/
class EmployeeCertificationAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'certification_id',
'institute',
'date_start',
'date_start',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Certification' },
{ sTitle: 'Institute' },
{ sTitle: 'Granted On' },
{ sTitle: 'Valid Thru' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['certification_id', {
label: 'Certification', type: 'select2', 'allow-null': false, 'remote-source': ['Certification', 'id', 'name'],
}],
['institute', { label: 'Institute', type: 'text', validation: '' }],
['date_start', { label: 'Granted On', type: 'date', validation: 'none' }],
['date_end', { label: 'Valid Thru', type: 'date', validation: 'none' }],
];
}
}
/**
* EmployeeLanguageAdapter
*/
class EmployeeLanguageAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'language_id',
'reading',
'speaking',
'writing',
'understanding',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Language' },
{ sTitle: 'Reading' },
{ sTitle: 'Speaking' },
{ sTitle: 'Writing' },
{ sTitle: 'Understanding' },
];
}
getFormFields() {
const compArray = [['Elementary Proficiency', 'Elementary Proficiency'],
['Limited Working Proficiency', 'Limited Working Proficiency'],
['Professional Working Proficiency', 'Professional Working Proficiency'],
['Full Professional Proficiency', 'Full Professional Proficiency'],
['Native or Bilingual Proficiency', 'Native or Bilingual Proficiency']];
return [
['id', { label: 'ID', type: 'hidden' }],
['language_id', {
label: 'Language', type: 'select2', 'allow-null': false, 'remote-source': ['Language', 'id', 'description'],
}],
['reading', { label: 'Reading', type: 'select', source: compArray }],
['speaking', { label: 'Speaking', type: 'select', source: compArray }],
['writing', { label: 'Writing', type: 'select', source: compArray }],
['understanding', { label: 'Understanding', type: 'select', source: compArray }],
];
}
}
module.exports = {
EmployeeSkillAdapter,
EmployeeEducationAdapter,
EmployeeCertificationAdapter,
EmployeeLanguageAdapter,
};

View File

@@ -0,0 +1,5 @@
import {
UserReportAdapter,
} from './lib';
window.UserReportAdapter = UserReportAdapter;

View File

@@ -0,0 +1,32 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import {
ReportAdapter,
} from '../../../admin/src/reports/lib';
/**
* UserReportAdapter
*/
class UserReportAdapter extends ReportAdapter {
renderForm(object) {
const that = this;
this.processFormFieldsWithObject(object);
if (this.remoteFieldsExists) {
const cb = function () {
that.renderFormNew(object);
};
this.initFieldMasterData(cb);
} else {
this.initFieldMasterData();
that.renderFormNew(object);
}
this.currentReport = object;
}
}
module.exports = { UserReportAdapter };

View File

@@ -0,0 +1,5 @@
import {
EmployeeSalaryAdapter,
} from './lib';
window.EmployeeSalaryAdapter = EmployeeSalaryAdapter;

View File

@@ -0,0 +1,36 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
class EmployeeSalaryAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'component',
'amount',
'details',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Salary Component' },
{ sTitle: 'Amount' },
{ sTitle: 'Details' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['component', { label: 'Salary Component', type: 'select2', 'remote-source': ['SalaryComponent', 'id', 'name'] }],
['amount', { label: 'Amount', type: 'text', validation: 'float' }],
['details', { label: 'Details', type: 'textarea', validation: 'none' }],
];
}
}
module.exports = { EmployeeSalaryAdapter };

View File

@@ -0,0 +1,7 @@
import {
StaffDirectoryAdapter,
StaffDirectoryObjectAdapter,
} from './lib';
window.StaffDirectoryAdapter = StaffDirectoryAdapter;
window.StaffDirectoryObjectAdapter = StaffDirectoryObjectAdapter;

View File

@@ -0,0 +1,173 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
import ObjectAdapter from '../../../api/ObjectAdapter';
class StaffDirectoryAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'image',
'first_name',
'last_name',
'job_title',
'department',
'work_phone',
'work_email',
'joined_date',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: '' },
{ sTitle: 'First Name' },
{ sTitle: 'Last Name' },
{ sTitle: 'Job Title' },
{ sTitle: 'Department' },
{ sTitle: 'Work Phone' },
{ sTitle: 'Work Email' },
{ sTitle: 'Joined Date' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden', validation: '' }],
['first_name', { label: 'First Name', type: 'text', validation: '' }],
['last_name', { label: 'Last Name', type: 'text', validation: '' }],
['job_title', { label: 'Job Title', type: 'select2', 'remote-source': ['JobTitle', 'id', 'name'] }],
['department', { label: 'Department', type: 'select2', 'remote-source': ['CompanyStructure', 'id', 'title'] }],
['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }],
['work_email', { label: 'Work Email', type: 'placeholder', validation: 'emailOrEmpty' }],
['joined_date', { label: 'Joined Date', type: 'date', validation: '' }],
];
}
showActionButtons() {
return false;
}
getCustomTableParams() {
const that = this;
const dataTableParams = {
aoColumnDefs: [
{
fnRender(data, cell) {
try {
return that.preProcessRemoteTableData(data, cell, 1);
} catch (e) { return cell; }
},
aTargets: [1],
},
{
fnRender(data, cell) {
try {
return that.preProcessRemoteTableData(data, cell, 8);
} catch (e) { return cell; }
},
aTargets: [8],
},
],
};
return dataTableParams;
}
// eslint-disable-next-line consistent-return
preProcessRemoteTableData(data, cell, id) {
if (id === 8) {
if (cell === '0000-00-00 00:00:00' || cell === '' || cell === undefined || cell === null) {
return '';
}
return Date.parse(cell).toString('yyyy MMM d');
} if (id === 1) {
const tmp = '<img src="_img_" class="img-circle" style="width:45px;height: 45px;" alt="User Image">';
return tmp.replace('_img_', cell);
}
}
}
/*
StaffDirectoryObjectAdapter
*/
class StaffDirectoryObjectAdapter extends ObjectAdapter {
getDataMapping() {
return [
'id',
'image',
'first_name',
'last_name',
'job_title',
'department',
'work_phone',
'work_email',
'joined_date',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: '' },
{ sTitle: 'First Name' },
{ sTitle: 'Last Name' },
{ sTitle: 'Job Title' },
{ sTitle: 'Department' },
{ sTitle: 'Work Phone' },
{ sTitle: 'Work Email' },
{ sTitle: 'Joined Date' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden', validation: '' }],
['first_name', { label: 'First Name', type: 'text', validation: '' }],
['last_name', { label: 'Last Name', type: 'text', validation: '' }],
['job_title', { label: 'Job Title', type: 'select2', 'remote-source': ['JobTitle', 'id', 'name'] }],
['department', { label: 'Department', type: 'select2', 'remote-source': ['CompanyStructure', 'id', 'title'] }],
['work_phone', { label: 'Work Phone', type: 'text', validation: 'none' }],
['work_email', { label: 'Work Email', type: 'placeholder', validation: 'emailOrEmpty' }],
['joined_date', { label: 'Joined Date', type: 'date', validation: '' }],
];
}
// eslint-disable-next-line no-unused-vars
addDomEvents(object) {
}
getTemplateName() {
return 'element.html';
}
preProcessTableData(_row) {
const row = _row;
row.color = this.getColorByRandomString(row.first_name);
return row;
}
getFilters() {
return [
['job_title', {
label: 'Job Title', type: 'select2', 'allow-null': true, 'null-label': 'All Job Titles', 'remote-source': ['JobTitle', 'id', 'name'],
}],
['department', {
label: 'Department', type: 'select2', 'allow-null': true, 'null-label': 'All Departments', 'remote-source': ['CompanyStructure', 'id', 'title'],
}],
];
}
}
module.exports = {
StaffDirectoryAdapter,
StaffDirectoryObjectAdapter,
};

View File

@@ -0,0 +1,11 @@
import {
EmployeeTimeSheetAdapter,
SubEmployeeTimeSheetAdapter,
EmployeeTimeEntryAdapter,
QtsheetAdapter,
} from './lib';
window.EmployeeTimeSheetAdapter = EmployeeTimeSheetAdapter;
window.SubEmployeeTimeSheetAdapter = SubEmployeeTimeSheetAdapter;
window.EmployeeTimeEntryAdapter = EmployeeTimeEntryAdapter;
window.QtsheetAdapter = QtsheetAdapter;

View File

@@ -0,0 +1,948 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
/* global modJs, modJsList, moment */
import AdapterBase from '../../../api/AdapterBase';
import FormValidation from '../../../api/FormValidation';
import TableEditAdapter from '../../../api/TableEditAdapter';
const ValidationRules = FormValidation.getValidationRules();
class EmployeeTimeSheetAdapter extends AdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.currentTimesheetId = null;
this.currentTimesheet = null;
this.needStartEndTime = false;
}
getDataMapping() {
return [
'id',
'date_start',
'date_end',
'total_time',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Start Date' },
{ sTitle: 'End Date' },
{ sTitle: 'Total Time' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['date_start', { label: 'TimeSheet Start Date', type: 'date', validation: '' }],
['date_end', { label: 'TimeSheet End Date', type: 'date', validation: '' }],
['details', { label: 'Reason', type: 'textarea', validation: 'none' }],
];
}
preProcessTableData(_row) {
const row = _row;
row[1] = Date.parse(row[1]).toString('MMM d, yyyy (dddd)');
row[2] = Date.parse(row[2]).toString('MMM d, yyyy (dddd)');
return row;
}
setNeedStartEndTime(status) {
this.needStartEndTime = status;
}
renderForm(object) {
const formHtml = this.templates.formTemplate;
$('#EmployeeTimesheetBlock').remove();
$(`#${this.getTableName()}Form`).html(formHtml);
$(`#${this.getTableName()}Form`).show();
$(`#${this.getTableName()}`).hide();
$('.timesheet_start').html(Date.parse(object.date_start).toString('MMM d, yyyy (dddd)'));
$('.timesheet_end').html(Date.parse(object.date_end).toString('MMM d, yyyy (dddd)'));
this.currentTimesheet = object;
this.getTimeEntries();
const st = Date.parse(object.date_start);
$('#EmployeeTimesheetBlock').fullCalendar({
header: {
// left: 'prev,next today',
left: false,
// center: 'title',
center: false,
// right: 'month,agendaWeek,agendaDay'
right: false,
},
year: st.toString('yyyy'),
month: st.toString('M'),
date: st.toString('d'),
defaultView: 'basicWeek',
height: 200,
editable: false,
events: modJs.getScheduleJsonUrl(this.currentTimesheet.employee),
loading(bool) {
if (bool) $('#loadingBlock').show();
else $('#loadingBlock').hide();
},
// eslint-disable-next-line no-unused-vars
dayClick(date, jsEvent, view, resourceObj) {
modJs.renderFormByDate(date.format());
},
// eslint-disable-next-line no-unused-vars
eventClick(calEvent, jsEvent, view) {
modJs.renderFormTimeEntryCalender(calEvent.id);
},
eventRender(event, element) {
element.find('.fc-time').remove();
},
});
$('#EmployeeTimesheetBlock').fullCalendar('gotoDate', st);
$('.fc-toolbar').hide();
}
quickEdit(id, status, sdate, edate) {
$('#Qtsheet').data('lastActiveTab', modJs.tab);
// eslint-disable-next-line no-global-assign
modJs = modJsList.tabQtsheet;
modJs.setCurrentTimeSheetId(id);
$('.timesheet_start').html(sdate);
$('.timesheet_end').html(edate);
$('#timesheetTabs').find('.active').find('.reviewBlock.reviewBlockTable').hide();
$('#QtsheetHeader').show();
$('#Qtsheet').show();
$('#QtsheetDataButtons').show();
if (status === 'Submitted' || status === 'Approved') {
$('.completeBtnTable').hide();
$('.saveBtnTable').hide();
} else {
$('.completeBtnTable').show();
$('.saveBtnTable').show();
}
modJs.get([]);
}
getScheduleJsonUrl(employeeId) {
const url = `${this.moduleRelativeURL}?a=ca&sa=getEmployeeTimeEntries&t=${this.table}&mod=modules%3Dtime_sheets&e=${employeeId}`;
return url;
}
renderFormByDate(_date) {
let date = _date;
if (date.indexOf('T') < 0) {
const s1 = moment();
date = `${date} ${s1.format('HH:mm:ss')}`;
}
const start = date.replace('T', ' ');
const m1 = moment(start);
m1.add(1, 'h');
const end = m1.format('YYYY-MM-DD HH:mm:ss');
const obj = {};
obj.date = _date;
obj.date_start = start;
obj.date_end = end;
this.renderFormTimeEntryCalender(obj);
}
renderFormTimeEntryCalender(object) {
if (`${this.needStartEndTime}` === '0') {
return;
}
this.openTimeEntryDialog(object);
if (object.id !== undefined && object.id != null) {
const cid = object.id;
$('.deleteBtnWorkSchedule').show();
$('.deleteBtnWorkSchedule').off().on('click', () => {
modJs.deleteRow(cid);
return false;
});
} else {
$('.deleteBtnWorkSchedule').remove();
}
}
openTimeEntryDialog(object) {
this.currentTimesheetId = this.currentId;
const obj = modJsList.tabEmployeeTimeEntry;
$('#TimeEntryModel').modal({
backdrop: 'static',
keyboard: false,
});
obj.currentTimesheet = this.currentTimesheet;
obj.renderForm(object);
obj.timesheetId = this.currentId;
}
closeTimeEntryDialog() {
$('#TimeEntryModel').modal('hide');
}
getTimeEntries() {
const timesheetId = this.currentId;
const sourceMappingJson = JSON.stringify(modJsList.tabEmployeeTimeEntry.getSourceMapping());
const object = { id: timesheetId, sm: sourceMappingJson };
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'getTimeEntriesSuccessCallBack';
callBackData.callBackFail = 'getTimeEntriesFailCallBack';
this.customAction('getTimeEntries', 'modules=time_sheets', reqJson, callBackData);
}
getTimeEntriesSuccessCallBack(callBackData) {
const entries = callBackData;
let html = '';
const temp = '<tr><td><img class="tableActionButton" src="_BASE_images/delete.png" style="cursor:pointer;" rel="tooltip" title="Delete" onclick="modJsList[\'tabEmployeeTimeEntry\'].deleteRow(_id_);return false;"></img></td><td>_start_</td><td>_end_</td><td>_duration_</td><td>_project_</td><td>_details_</td>';
for (let i = 0; i < entries.length; i++) {
try {
let t = temp;
t = t.replace(/_start_/g, Date.parse(entries[i].date_start).toString('MMM d, yyyy [hh:mm tt]'));
t = t.replace(/_end_/g, Date.parse(entries[i].date_end).toString('MMM d, yyyy [hh:mm tt]'));
const mili = Date.parse(entries[i].date_end) - Date.parse(entries[i].date_start);
const minutes = Math.round(mili / 60000);
const hourMinutes = (minutes % 60);
const hours = (minutes - hourMinutes) / 60;
t = t.replace(/_duration_/g, `Hours (${hours}) - Min (${hourMinutes})`);
if (entries[i].project === 'null' || entries[i].project == null || entries[i].project === undefined) {
t = t.replace(/_project_/g, 'None');
} else {
t = t.replace(/_project_/g, entries[i].project);
}
t = t.replace(/_project_/g, entries[i].project);
t = t.replace(/_details_/g, entries[i].details);
t = t.replace(/_id_/g, entries[i].id);
t = t.replace(/_BASE_/g, this.baseUrl);
html += t;
} catch (e) {
// Do nothing
}
}
$('.timesheet_entries_table_body').html(html);
if (modJs.getTableName() === 'SubEmployeeTimeSheetAll' || `${this.needStartEndTime}` === '0') {
$('.submit_sheet').hide();
$('.add_time_sheet_entry').hide();
} else if (this.currentElement.status === 'Approved') {
$('.submit_sheet').hide();
$('.add_time_sheet_entry').hide();
} else {
$('.submit_sheet').show();
$('.add_time_sheet_entry').show();
}
$('#EmployeeTimesheetBlock').fullCalendar('refetchEvents');
}
// eslint-disable-next-line no-unused-vars
getTimeEntriesFailCallBack(callBackData) {
this.showMessage('Error', 'Error occured while getting timesheet entries');
}
createPreviousTimesheet(id) {
const object = { id };
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'createPreviousTimesheetSuccessCallBack';
callBackData.callBackFail = 'createPreviousTimesheetFailCallBack';
this.customAction('createPreviousTimesheet', 'modules=time_sheets', reqJson, callBackData);
}
// eslint-disable-next-line no-unused-vars
createPreviousTimesheetSuccessCallBack(callBackData) {
$('.tooltip').css('display', 'none');
$('.tooltip').remove();
// this.showMessage("Success", "Previous Timesheet created");
this.get([]);
}
createPreviousTimesheetFailCallBack(callBackData) {
this.showMessage('Error', callBackData);
}
changeTimeSheetStatusWithId(id, status) {
if (status === '' || status == null || status === undefined) {
this.showMessage('Status Error', 'Please select a status');
return;
}
const object = { id, status };
const reqJson = JSON.stringify(object);
const callBackData = [];
callBackData.callBackData = [];
callBackData.callBackSuccess = 'changeTimeSheetStatusSuccessCallBack';
callBackData.callBackFail = 'changeTimeSheetStatusFailCallBack';
this.customAction('changeTimeSheetStatus', 'modules=time_sheets', reqJson, callBackData);
}
// eslint-disable-next-line no-unused-vars
changeTimeSheetStatusSuccessCallBack(callBackData) {
this.showMessage('Successful', 'Timesheet status changed successfully');
this.get([]);
}
// eslint-disable-next-line no-unused-vars
changeTimeSheetStatusFailCallBack(callBackData) {
this.showMessage('Error', 'Error occured while changing Timesheet status');
}
getActionButtonsHtml(id, data) {
let html = '';
if (`${this.needStartEndTime}` === '0') {
html = '<div style="width:100px;">'
+ '<img class="tableActionButton" src="_BASE_images/view.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img>'
+ '<img class="tableActionButton" src="_BASE_images/edit.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.quickEdit(_id_,\'_status_\',\'_sdate_\',\'_edate_\');return false;"></img>'
+ '_redoBtn_'
+ '</div>';
} else {
html = '<div style="width:80px;">'
+ '<img class="tableActionButton" src="_BASE_images/edit.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img>'
+ '_redoBtn_'
+ '</div>';
}
if (this.getTableName() === 'EmployeeTimeSheetAll') {
const redoBtn = '<img class="tableActionButton" src="_BASE_images/redo.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Create previous time sheet" onclick="modJs.createPreviousTimesheet(_id_);return false;"></img>';
html = html.replace(/_redoBtn_/g, redoBtn);
} else {
html = html.replace(/_redoBtn_/g, '');
}
html = html.replace(/_id_/g, id);
html = html.replace(/_sdate_/g, data[1]);
html = html.replace(/_edate_/g, data[2]);
html = html.replace(/_status_/g, data[4]);
html = html.replace(/_BASE_/g, this.baseUrl);
return html;
}
getCustomTableParams() {
const that = this;
const dataTableParams = {
aoColumnDefs: [
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 1);
},
aTargets: [1],
},
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 2);
},
aTargets: [2],
},
{
fnRender: that.getActionButtons,
aTargets: [that.getDataMapping().length],
},
],
};
return dataTableParams;
}
// eslint-disable-next-line no-unused-vars
preProcessRemoteTableData(data, cell, id) {
return Date.parse(cell).toString('MMM d, yyyy (dddd)');
}
}
/*
* Subordinate TimeSheets
*/
class SubEmployeeTimeSheetAdapter extends EmployeeTimeSheetAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.timeSheetStatusChangeId = null;
}
getDataMapping() {
return [
'id',
'employee',
'date_start',
'date_end',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Employee', bSearchable: true },
{ sTitle: 'Start Date', bSearchable: true },
{ sTitle: 'End Date', bSearchable: true },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['employee', {
label: 'Employee', type: 'select', 'allow-null': false, 'remote-source': ['Employee', 'id', 'first_name+last_name'],
}],
['date_start', { label: 'TimeSheet Start Date', type: 'date', validation: '' }],
['date_end', { label: 'TimeSheet Start Date', type: 'date', validation: '' }],
['details', { label: 'Reason', type: 'textarea', validation: 'none' }],
];
}
isSubProfileTable() {
return true;
}
getCustomSuccessCallBack(serverData) {
const data = [];
const mapping = this.getDataMapping();
for (let i = 0; i < serverData.length; i++) {
const row = [];
for (let j = 0; j < mapping.length; j++) {
row[j] = serverData[i][mapping[j]];
}
data.push(this.preProcessTableData(row));
}
this.tableData = data;
this.createTable(this.getTableName());
$(`#${this.getTableName()}Form`).hide();
$(`#${this.getTableName()}`).show();
}
preProcessTableData(_row) {
const row = _row;
row[2] = Date.parse(row[2]).toString('MMM d, yyyy (dddd)');
row[3] = Date.parse(row[3]).toString('MMM d, yyyy (dddd)');
return row;
}
openTimeSheetStatus(timeSheetId, status) {
this.currentTimesheetId = timeSheetId;
$('#TimeSheetStatusModel').modal('show');
$('#timesheet_status').val(status);
this.timeSheetStatusChangeId = timeSheetId;
}
closeTimeSheetStatus() {
$('#TimeSheetStatusModel').modal('hide');
}
changeTimeSheetStatus() {
const timeSheetStatus = $('#timesheet_status').val();
this.changeTimeSheetStatusWithId(this.timeSheetStatusChangeId, timeSheetStatus);
this.closeTimeSheetStatus();
this.timeSheetStatusChangeId = null;
}
getActionButtonsHtml(id, data) {
let html;
if (`${this.needStartEndTime}` === '0') {
html = '<div style="width:100px;">'
+ '<img class="tableActionButton" src="_BASE_images/view.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img>'
+ '<img class="tableActionButton" src="_BASE_images/edit.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.quickEdit(_id_,\'_status_\',\'_sdate_\',\'_edate_\');return false;"></img>'
+ '<img class="tableActionButton" src="_BASE_images/run.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Change TimeSheet Status" onclick="modJs.openTimeSheetStatus(_id_,\'_status_\');return false;"></img>'
+ '</div>';
} else {
html = '<div style="width:80px;">'
+ '<img class="tableActionButton" src="_BASE_images/edit.png" style="cursor:pointer;" rel="tooltip" title="Edit Timesheet Entries" onclick="modJs.edit(_id_);return false;"></img>'
+ '<img class="tableActionButton" src="_BASE_images/run.png" style="cursor:pointer;margin-left:15px;" rel="tooltip" title="Change TimeSheet Status" onclick="modJs.openTimeSheetStatus(_id_,\'_status_\');return false;"></img>'
+ '</div>';
}
html = html.replace(/_id_/g, id);
html = html.replace(/_BASE_/g, this.baseUrl);
html = html.replace(/_sdate_/g, data[1]);
html = html.replace(/_edate_/g, data[2]);
html = html.replace(/_status_/g, data[4]);
return html;
}
getCustomTableParams() {
const that = this;
const dataTableParams = {
aoColumnDefs: [
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 2);
},
aTargets: [2],
},
{
fnRender(data, cell) {
return that.preProcessRemoteTableData(data, cell, 3);
},
aTargets: [3],
},
{
fnRender: that.getActionButtons,
aTargets: [that.getDataMapping().length],
},
],
};
return dataTableParams;
}
getFilters() {
return [
['employee', {
label: 'Employee', type: 'select2', 'allow-null': true, 'null-label': 'All Employees', 'remote-source': ['Employee', 'id', 'first_name+last_name'],
}],
['status', {
label: 'Status', type: 'select', 'allow-null': true, 'null-label': 'All', source: [['Submitted', 'Submitted'], ['Pending', 'Pending'], ['Approved', 'Approved'], ['Rejected', 'Rejected']],
}],
];
}
}
/**
* EmployeeTimeEntryAdapter
*/
class EmployeeTimeEntryAdapter extends AdapterBase {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.timesheetId = null;
this.currentTimesheet = null;
this.allProjectsAllowed = 1;
this.employeeProjects = [];
}
getDataMapping() {
return [
'id',
'project',
'date_start',
'time_start',
'date_end',
'time_end',
'details',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Project' },
{ sTitle: 'Start Date' },
{ sTitle: 'Start Time' },
{ sTitle: 'End Date' },
{ sTitle: 'End Time' },
{ sTitle: 'Details' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['project', {
label: 'Project', type: 'select2', 'allow-null': false, 'remote-source': ['Project', 'id', 'name', 'getEmployeeProjects'],
}],
['date_select', { label: 'Date', type: 'select', source: [] }],
['date_start', { label: 'Start Time', type: 'time', validation: '' }],
['date_end', { label: 'End Time', type: 'time', validation: '' }],
['details', { label: 'Details', type: 'textarea', validation: '' }],
];
}
getDates(startDate, stopDate) {
const dateArray = [];
let currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(new Date(currentDate));
currentDate = currentDate.add({ days: 1 });
}
return dateArray;
}
renderForm(object) {
let formHtml = this.getCustomTemplate('time_entry_form.html');
formHtml = formHtml.replace(/modJs/g, "modJsList['tabEmployeeTimeEntry']");
let html = '';
const fields = this.getFormFields();
for (let i = 0; i < fields.length; i++) {
const metaField = this.getMetaFieldForRendering(fields[i][0]);
if (metaField === '' || metaField === undefined) {
html += this.renderFormField(fields[i]);
} else {
const metaVal = object[metaField];
if (metaVal !== '' && metaVal != null && metaVal !== undefined && metaVal.trim() !== '') {
html += this.renderFormField(JSON.parse(metaVal));
} else {
html += this.renderFormField(fields[i]);
}
}
}
// append dates
// var dateStart = new Date(this.currentTimesheet.date_start);
// var dateStop = new Date(this.currentTimesheet.date_end);
// var datesArray = this.getDates(dateStart, dateStop);
let optionList = '';
for (let i = 0; i < this.currentTimesheet.days.length; i++) {
const k = this.currentTimesheet.days[i];
// optionList += '<option value="'+timeUtils.getMySQLFormatDate(k)+'">'+k.toUTCString().slice(0, -13)+'</option>';
optionList += `<option value="${k[0]}">${k[1]}</option>`;
}
formHtml = formHtml.replace(/_id_/g, `${this.getTableName()}_submit`);
formHtml = formHtml.replace(/_fields_/g, html);
$(`#${this.getTableName()}Form`).html(formHtml);
$(`#${this.getTableName()}Form`).show();
$(`#${this.getTableName()}`).hide();
$(`#${this.getTableName()}Form .datefield`).datepicker({ viewMode: 2 });
$(`#${this.getTableName()}Form .datetimefield`).datetimepicker({
language: 'en',
});
$(`#${this.getTableName()}Form .timefield`).datetimepicker({
language: 'en',
pickDate: false,
});
$(`#${this.getTableName()}Form .select2Field`).select2();
$('#date_select').html(optionList);
if (object !== undefined && object != null) {
this.fillForm(object);
}
}
// eslint-disable-next-line no-unused-vars
fillForm(object, _formId, fields) {
let formId = _formId;
if (formId == null || formId === undefined || formId === '') {
formId = `#${this.getTableName()}Form`;
}
if (object.id != null && object.id !== undefined) {
$(`${formId} #id`).val(object.id);
}
if (object.project != null && object.project !== undefined) {
$(`${formId} #project`).select2('val', object.project);
}
if (object.date != null && object.date !== undefined) {
$(`${formId} #date_select`).val(object.date);
}
}
cancel() {
$('#TimeEntryModel').modal('hide');
}
setAllProjectsAllowed(allProjectsAllowed) {
this.allProjectsAllowed = allProjectsAllowed;
}
setEmployeeProjects(employeeProjects) {
this.employeeProjects = employeeProjects;
}
save() {
const validator = new FormValidation(`${this.getTableName()}_submit`, true, { ShowPopup: false, LabelErrorClass: 'error' });
if (validator.checkValues()) {
const params = validator.getFormParameters();
params.timesheet = this.timesheetId;
params.time_start = params.date_start;
params.time_end = params.date_end;
params.date_start = `${params.date_select} ${params.date_start}`;
params.date_end = `${params.date_select} ${params.date_end}`;
const msg = this.doCustomValidation(params);
if (msg == null) {
const id = $(`#${this.getTableName()}_submit #id`).val();
if (id != null && id !== undefined && id !== '') {
params.id = id;
}
this.add(params, []);
this.cancel();
} else {
$(`#${this.getTableName()}Form .label`).html(msg);
$(`#${this.getTableName()}Form .label`).show();
}
}
}
doCustomValidation(params) {
const st = Date.parse(params.date_start);
const et = Date.parse(params.date_end);
if (st.compareTo(et) !== -1) {
return 'Start time should be less than End time';
}
/*
var sd = Date.parse(this.currentTimesheet.date_start);
var ed = Date.parse(this.currentTimesheet.date_end).addDays(1);
if(sd.compareTo(et) != -1 || sd.compareTo(st) > 0 || st.compareTo(ed) != -1 || et.compareTo(ed) != -1){
return "Start time and end time shoud be with in " + sd.toString('MMM d, yyyy (dddd)') + " and " + ed.toString('MMM d, yyyy (dddd)');
}
*/
return null;
}
// eslint-disable-next-line no-unused-vars
addSuccessCallBack(callBackData, serverData) {
this.get(callBackData);
modJs.getTimeEntries();
}
deleteRow(id) {
this.deleteObj(id, []);
}
// eslint-disable-next-line no-unused-vars
deleteSuccessCallBack(callBackData, serverData) {
modJs.getTimeEntries();
}
}
/**
* QtsheetAdapter
*/
class QtsheetAdapter extends TableEditAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.cellDataUpdates = {};
this.currentId = null;
}
validateCellValue(element, evt, newValue) {
if (!ValidationRules.float(newValue)) {
return false;
}
const val = parseFloat(newValue);
if (val < 0 || val > 24) {
return false;
}
// Update total
// Find current column number
// Adding 2 because nth child is based on 1 and we are adding a virtual column for row names
const coldNum = this.columnIDMap[element.data('colId')] + 2;
let columnTotal = 0;
let columnTotalWithoutCurrent = 0;
$(`#${this.getTableName()} tr td:nth-child(${coldNum})`).each(function () {
const rowId = $(this).data('rowId');
let tval = '';
if (element.data('rowId') === rowId) {
tval = newValue;
} else {
tval = $(this).html();
}
if (rowId !== -1) {
if (ValidationRules.float(tval)) {
columnTotal += parseFloat(tval);
if (element.data('rowId') !== rowId) {
columnTotalWithoutCurrent += parseFloat(tval);
}
}
} else if (columnTotal > 24) {
$(this).html(columnTotalWithoutCurrent);
} else {
$(this).html(columnTotal);
}
});
if (columnTotal > 24) {
return false;
}
modJs.addCellDataUpdate(element.data('colId'), element.data('rowId'), newValue);
return true;
}
setCurrentTimeSheetId(val) {
this.currentId = val;
this.cellDataUpdates = {};
}
addAdditionalRequestData(type, req) {
if (type === 'updateData') {
req.currentId = this.currentId;
} else if (type === 'updateAllData') {
req.currentId = this.currentId;
} else if (type === 'getAllData') {
req.currentId = this.currentId;
}
return req;
}
modifyCSVHeader(header) {
header.unshift('');
return header;
}
getCSVData() {
let csv = '';
for (let i = 0; i < this.csvData.length; i++) {
csv += this.csvData[i].join(',');
if (i < this.csvData.length - 1) {
csv += '\r\n';
}
}
return csv;
}
downloadTimesheet() {
const element = document.createElement('a');
element.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(this.getCSVData())}`);
element.setAttribute('download', `timesheet_${this.currentId}.csv`);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
createTable(elementId) {
const data = this.getTableData();
const headers = this.getHeaders();
if (this.showActionButtons()) {
headers.push({ sTitle: '', sClass: 'center' });
}
if (this.showActionButtons()) {
for (let i = 0; i < data.length; i++) {
data[i].push(this.getActionButtonsHtml(data[i][0], data[i]));
}
}
let html = '';
html = `${this.getTableTopButtonHtml()}<div class="box-body table-responsive"><table cellpadding="0" cellspacing="0" border="0" class="table table-bordered table-striped" id="grid"></table></div>`;
// Find current page
const activePage = $(`#${elementId} .dataTables_paginate .active a`).html();
let start = 0;
if (activePage !== undefined && activePage !== null) {
start = parseInt(activePage, 10) * 100 - 100;
}
$(`#${elementId}`).html(html);
const dataTableParams = {
oLanguage: {
sLengthMenu: '_MENU_ records per page',
},
aaData: data,
aoColumns: headers,
bSort: false,
iDisplayLength: 100,
iDisplayStart: start,
};
const customTableParams = this.getCustomTableParams();
$.extend(dataTableParams, customTableParams);
$(`#${elementId} #grid`).dataTable(dataTableParams);
$(`#${elementId} #grid tr:last`).find('td').removeClass('editcell');
$('.dataTables_paginate ul').addClass('pagination');
$('.dataTables_length').hide();
$('.dataTables_filter input').addClass('form-control');
$('.dataTables_filter input').attr('placeholder', 'Search');
$('.dataTables_filter label').contents().filter(function () {
return (this.nodeType === 3);
}).remove();
// $('.tableActionButton').tooltip();
$(`#${elementId} #grid`).editableTableWidget();
$(`#${elementId} #grid .editcell`).on('validate', function (evt, newValue) {
return modJs.validateCellValue($(this), evt, newValue);
});
}
}
module.exports = {
EmployeeTimeSheetAdapter,
SubEmployeeTimeSheetAdapter,
EmployeeTimeEntryAdapter,
QtsheetAdapter,
};

View File

@@ -0,0 +1,11 @@
import {
EmployeeImmigrationAdapter,
EmployeeTravelRecordAdapter,
EmployeeTravelRecordApproverAdapter,
SubordinateEmployeeTravelRecordAdapter,
} from './lib';
window.EmployeeImmigrationAdapter = EmployeeImmigrationAdapter;
window.EmployeeTravelRecordAdapter = EmployeeTravelRecordAdapter;
window.EmployeeTravelRecordApproverAdapter = EmployeeTravelRecordApproverAdapter;
window.SubordinateEmployeeTravelRecordAdapter = SubordinateEmployeeTravelRecordAdapter;

View File

@@ -0,0 +1,181 @@
/*
Copyright (c) 2018 [Glacies UG, Berlin, Germany] (http://glacies.de)
Developer: Thilina Hasantha (http://lk.linkedin.com/in/thilinah | https://github.com/thilinah)
*/
import AdapterBase from '../../../api/AdapterBase';
import ApproveModuleAdapter from '../../../api/ApproveModuleAdapter';
import {
EmployeeTravelRecordAdminAdapter,
} from '../../../admin/src/travel/lib';
class EmployeeImmigrationAdapter extends AdapterBase {
getDataMapping() {
return [
'id',
'document',
'documentname',
'valid_until',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Document' },
{ sTitle: 'Document Id' },
{ sTitle: 'Valid Until' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return [
['id', { label: 'ID', type: 'hidden' }],
['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' }],
];
}
}
class EmployeeTravelRecordAdapter extends ApproveModuleAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.itemName = 'Travel';
this.itemNameLower = 'employeetravelrecord';
this.modulePathName = 'travel';
}
getDataMapping() {
return [
'id',
'type',
'purpose',
'travel_from',
'travel_to',
'travel_date',
'return_date',
'status',
];
}
getHeaders() {
return [
{ sTitle: 'ID', bVisible: false },
{ sTitle: 'Travel Type' },
{ sTitle: 'Purpose' },
{ sTitle: 'From' },
{ sTitle: 'To' },
{ sTitle: 'Travel Date' },
{ sTitle: 'Return Date' },
{ sTitle: 'Status' },
];
}
getFormFields() {
return this.addCustomFields([
['id', { label: 'ID', type: 'hidden' }],
['type', {
label: 'Means of Transportation',
type: 'select',
source: [
['Plane', 'Plane'],
['Rail', 'Rail'],
['Taxi', 'Taxi'],
['Own Vehicle', 'Own Vehicle'],
['Rented Vehicle', 'Rented Vehicle'],
['Other', 'Other'],
],
}],
['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', default: '0.00', mask: '9{0,10}.99',
}],
['attachment1', { label: 'Attachment', type: 'fileupload', validation: 'none' }],
['attachment2', { label: 'Attachment', type: 'fileupload', validation: 'none' }],
['attachment3', { label: 'Attachment', type: 'fileupload', validation: 'none' }],
]);
}
}
/*
EmployeeTravelRecordApproverAdapter
*/
class EmployeeTravelRecordApproverAdapter extends EmployeeTravelRecordAdminAdapter {
constructor(endPoint, tab, filter, orderBy) {
super(endPoint, tab, filter, orderBy);
this.itemName = 'Travel';
this.itemNameLower = 'employeetravelrecord';
this.modulePathName = 'travel';
}
getActionButtonsHtml(id, data) {
const statusChangeButton = '<img class="tableActionButton" src="_BASE_images/run.png" style="cursor:pointer;" rel="tooltip" title="Change Status" onclick="modJs.openStatus(_id_, \'_cstatus_\');return false;"></img>';
const viewLogsButton = '<img class="tableActionButton" src="_BASE_images/log.png" style="margin-left:15px;cursor:pointer;" rel="tooltip" title="View Logs" onclick="modJs.getLogs(_id_);return false;"></img>';
let html = '<div style="width:80px;">_status__logs_</div>';
html = html.replace('_logs_', viewLogsButton);
if (data[this.getStatusFieldPosition()] === 'Processing') {
html = html.replace('_status_', statusChangeButton);
} else {
html = html.replace('_status_', '');
}
html = html.replace(/_id_/g, id);
html = html.replace(/_BASE_/g, this.baseUrl);
html = html.replace(/_cstatus_/g, data[this.getStatusFieldPosition()]);
return html;
}
getStatusOptionsData(currentStatus) {
const data = {};
if (currentStatus === 'Processing') {
data.Approved = 'Approved';
data.Rejected = 'Rejected';
}
return data;
}
getStatusOptions(currentStatus) {
return this.generateOptions(this.getStatusOptionsData(currentStatus));
}
}
/*
SubordinateExpenseModuleAdapter
*/
class SubordinateEmployeeTravelRecordAdapter extends EmployeeTravelRecordAdminAdapter {
}
module.exports = {
EmployeeImmigrationAdapter,
EmployeeTravelRecordAdapter,
EmployeeTravelRecordApproverAdapter,
SubordinateEmployeeTravelRecordAdapter,
};