Compare commits

...

22 Commits

Author SHA1 Message Date
6b22fc4694 [add] Loading salary data 2018-08-14 07:38:25 -06:00
caa31136f1 [add] Endpoint to calculate salary 2018-08-14 04:06:36 -06:00
568c6d23a9 [add] Validating date isn't duplicated 2018-08-14 02:30:56 -06:00
15a7ea5ef5 [add] Saving worked day 2018-08-14 02:11:07 -06:00
93099d316f [add] Sending new work day data to backend 2018-08-14 00:26:25 -06:00
e9f80a9989 [add] Enabling covered rol for aux 2018-08-14 00:16:06 -06:00
6ce90bd318 [add] Loading basic employee data 2018-08-14 00:08:05 -06:00
69e3a31d52 [add] Layout new work day 2018-08-14 00:00:47 -06:00
1ee650e020 [add] Instantiating the new view 2018-08-13 23:20:37 -06:00
61eb809204 [add] Database and settings 2018-08-13 22:58:49 -06:00
b98b4077b4 Merge pull request #20 from PootisPenserHere/updatingEmployeeDataFromView
Updating employee data from view
2018-08-12 23:18:47 -06:00
a8148bbb93 [add] Employee updated 2018-08-12 23:17:20 -06:00
b0a19c6daa [add] Loading employee data 2018-08-12 22:55:00 -06:00
38d3466f16 [fix] Returning idEmployeeType instead of name type 2018-08-12 22:49:32 -06:00
68723e82fe [add] Searching for full employee data by code
Corrected a logical  error where the wrong method was being called to get data by code and also made it so the search function only returns names and codes
2018-08-12 22:22:33 -06:00
6615e5471a [add] Bloodhound in local files 2018-08-12 21:51:09 -06:00
49e114c18a [add] Bloodhoung search 2018-08-12 21:45:50 -06:00
e9effb7fcc [add] Finding employees by name 2018-08-12 21:01:46 -06:00
a5a1656518 [add] New asserts 2018-08-12 19:48:34 -06:00
19d1f57240 [mod] File naming 2018-08-12 19:28:50 -06:00
99a020024e Merge pull request #19 from PootisPenserHere/creatingNewEmployeeFromView
Creating new employee from view
2018-08-12 19:22:13 -06:00
dc45f02ad2 Merge pull request #18 from PootisPenserHere/loadingViews
Loading views
2018-08-12 11:36:52 -06:00
13 changed files with 3583 additions and 14 deletions

View File

@@ -0,0 +1,111 @@
<script src="../js/getBaseUrl.js"></script>
<script src="../js/editEmployee.js"></script>
<form class="form-horizontal" id="editEmployee">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Edit employee</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmploySearch">Employee</label>
<div class="col-md-5">
<input id="editEmploySearch" name="editEmploySearch" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeFirstName">First name</label>
<div class="col-md-5">
<input id="editEmployeeFirstName" name="editEmployeeFirstName" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeMiddleName">Middle name</label>
<div class="col-md-5">
<input id="editEmployeeMiddleName" name="editEmployeeMiddleName" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeLastName">Last name</label>
<div class="col-md-5">
<input id="editEmployeeLastName" name="editEmployeeLastName" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeBirthDate">Birth date</label>
<div class="col-md-5">
<input id="editEmployeeBirthDate" name="editEmployeeBirthDate" type="text" class="form-control input-md datepicker">
</div>
</div>
</div>
<div class="row" id="hidenEmployeeCode">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeCode">Code</label>
<div class="col-md-5">
<input id="editEmployeeCode" name="editEmployeeCode" type="text" class="form-control input-md">
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeEmail">Email</label>
<div class="col-md-5">
<input id="editEmployeeEmail" name="editEmployeeEmail" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeePhone">Phone</label>
<div class="col-md-5">
<input id="editEmployeePhone" name="editEmployeePhone" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeType">Rol</label>
<div class="col-md-5">
<select class="form-control input-md" name="editEmployeeType" id="editEmployeeType">
<option>Employee type</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="editEmployeeContractType">Contract type</label>
<div class="col-md-5">
<select class="form-control input-md" name="editEmployeeContractType" id="editEmployeeContractType">
<option>Contract type</option>
<option value="INTERNO">interno</option>
<option value="EXTERNO">Externo</option>
</select>
</div>
</div>
</div>
</div>
<div class="row col-md-offset-6">
<div class="form-group">
<a href="#" class="btn btn-lg btn-success " onclick="updateEmployee();">Update</a>
</div>
</div>
</div>
</div>
</div>
</form>

View File

@@ -31,14 +31,14 @@ if(!isset($_SESSION['userName'])){
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-user"></span> Employees<span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-user"></span> Employees<span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="#" data-nav_accion="NewEmployee.php"> New employee</a></li> <li><a href="#" data-nav_accion="newEmployee.php"> New employee</a></li>
<li><a href="#" data-nav_accion="EditEmployee.php"> Modify employee</a></li> <li><a href="#" data-nav_accion="editEmployee.php"> Modify employee</a></li>
</ul> </ul>
</li> </li>
<li> <li>
<a href="#" onclick="loadView();"><span class="glyphicon glyphicon-tasks"></span> Management</a> <a href="#" data-nav_accion="registerWorkDays.php" ><span class="glyphicon glyphicon-tasks"></span> Management</a>
</li> </li>
<li> <li>
@@ -226,6 +226,7 @@ if(!isset($_SESSION['userName'])){
<script src="../js/getBaseUrl.js"></script> <script src="../js/getBaseUrl.js"></script>
<script src="../js/landing.js"></script> <script src="../js/landing.js"></script>
<script src="../js/bootstrap-datepicker.min.js"></script> <script src="../js/bootstrap-datepicker.min.js"></script>
<script src="../js/typeahead.bundle.js"></script>
<link href="../css/bootstrap-datepicker.min.css" rel="stylesheet"> <link href="../css/bootstrap-datepicker.min.css" rel="stylesheet">
<link href="../css/landing.css" rel="stylesheet"> <link href="../css/landing.css" rel="stylesheet">

View File

@@ -1,4 +1,4 @@
<script src="../js/NewEmployee.js"></script> <script src="../js/newEmployee.js"></script>
<script src="../js/getBaseUrl.js"></script> <script src="../js/getBaseUrl.js"></script>
<form class="form-horizontal" id="newEmployeeForm"> <form class="form-horizontal" id="newEmployeeForm">

View File

@@ -0,0 +1,134 @@
<script src="../js/getBaseUrl.js"></script>
<script src="../js/registerWorkDays.js"></script>
<form class="form-horizontal" id="workDaysForm">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Managing work days</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysSearchEmployee">Employee</label>
<div class="col-md-5">
<input id="workDaysSearchEmployee" name="workDaysSearchEmployee" type="text" class="form-control input-md">
</div>
</div>
</div>
</div>
<div id="registerWorkDaysEmployeeInfo" class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeName">Name</label>
<div class="col-md-5">
<input id="workDaysEmployeeName" name="workDaysEmployeeName" type="text" class="form-control input-md" disabled>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeRol">Rol</label>
<div class="col-md-5">
<select class="form-control input-md" name="workDaysEmployeeRol" id="workDaysEmployeeRol" disabled>
<option></option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeContractType">Contract type</label>
<div class="col-md-5">
<select class="form-control input-md" name="workDaysEmployeeContractType" id="workDaysEmployeeContractType" disabled>
<option>Contract type</option>
<option value="INTERNO">interno</option>
<option value="EXTERNO">Externo</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeWorkedDay">Date</label>
<div class="col-md-5">
<input id="workDaysEmployeeWorkedDay" name="workDaysEmployeeWorkedDay" type="text" class="form-control input-md datepicker">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeDeliveries">Deliveries</label>
<div class="col-md-5">
<input id="workDaysEmployeeDeliveries" name="workDaysEmployeeDeliveries" type="number" value="0" class="form-control input-md">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeePerformedRol">Performed rol</label>
<div class="col-md-5">
<select class="form-control input-md" name="workDaysEmployeePerformedRol" id="workDaysEmployeePerformedRol" disabled>
<option>Employee type</option>
</select>
</div>
</div>
</div>
</div>
<div id="registerWorkDaysEmployeeSalary" class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeSalaryRaw">Raw</label>
<div class="col-md-5">
<input id="workDaysEmployeeSalaryRaw" name="workDaysEmployeeSalaryRaw" type="text" class="form-control input-md" disabled>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeSalaryTaxes">Taxes</label>
<div class="col-md-5">
<input id="workDaysEmployeeSalaryTaxes" name="workDaysEmployeeSalaryTaxes" type="text" class="form-control input-md" disabled>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeSalaryFinal">Final</label>
<div class="col-md-5">
<input id="workDaysEmployeeSalaryFinal" name="workDaysEmployeeSalaryFinal" type="text" class="form-control input-md" disabled>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="workDaysEmployeeSalaryVouchers">Vouchers</label>
<div class="col-md-5">
<input id="workDaysEmployeeSalaryVouchers" name="workDaysEmployeeSalaryVouchers" type="text" class="form-control input-md" disabled>
</div>
</div>
</div>
</div>
<div class="row" id="hidenEmployeeCodeForWorkDays">
<div class="form-group">
<label class="col-md-4 control-label" for="hidenEmployeeCodeForWorkDaysCode">Code</label>
<div class="col-md-5">
<input id="hidenEmployeeCodeForWorkDaysCode" name="hidenEmployeeCodeForWorkDaysCode" type="text" class="form-control input-md">
</div>
</div>
</div>
<div class="row col-md-offset-6">
<div class="form-group">
<a href="#" class="btn btn-lg btn-success " onclick="saveNewWorkDay();">Save</a>
</div>
</div>
</div>
</div>
</form>

View File

@@ -0,0 +1,180 @@
/**
* Bootstrapping the starting actions for the module
*/
$(document).ready(function(){
let baseUrl = getbaseUrl();
loadEmployeeTypes();
$('.datepicker').datepicker({
format: "yyyy/mm/dd",
autoclose: true
});
// Not to be edited
$("#hidenEmployeeCode").hide();
// Setting up bloodhound typeahead
let employeesList = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
'cache': false,
url: baseUrl + '/api/employee/find',
replace: function(url, uriEncodedQuery) {
return url + '/' + uriEncodedQuery
},
wildcard: '%QUERY',
filter: function (data) {
return data;
}
}
});
employeesList.initialize();
$("#editEmploySearch").typeahead({
hint: true,
highlight: true,
minLength: 3
},
{
name: "result",
displayKey: "fullName",
source: employeesList.ttAdapter()
}).bind("typeahead:selected", function(obj, datum, name) {
$(this).data("id", datum.code);
loadEmployeeData(datum.code);
});
});
/**
* Loads the the employee types into their select option
*/
function loadEmployeeTypes(){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/types',
type: 'GET',
dataType: 'json',
success:function(data){
$(data).each(function(i,v){
$('#editEmployeeType').append(
'<option value="' + v.id + '">'+ v.name + '</option>'
);
});
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
/**
* Searches the employee data by its employee code and loads it
* into the form to be edited and updated
*
* @param code string
*/
function loadEmployeeData(code){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/code/' + code,
type: 'GET',
dataType: 'json',
success:function(data){
$('#editEmployeeFirstName').val(data['firstName']);
$('#editEmployeeMiddleName').val(data['middleName']);
$('#editEmployeeLastName').val(data['lastName']);
$('#editEmployeeBirthDate').val(data['birthDate']);
$('#editEmployeeCode').val(data['code']);
$('#editEmployeeEmail').val(data['email']);
$('#editEmployeePhone').val(data['phone']);
$('#editEmployeeType').val(data['idEmployeeType']);
$('#editEmployeeContractType').val(data['contractType']);
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
function updateEmployee(){
let baseUrl = getbaseUrl();
let parameters = {
"firstName":$('#editEmployeeFirstName').val(),
"middleName":$('#editEmployeeMiddleName').val(),
"lastName":$('#editEmployeeLastName').val(),
"birthDate":$('#editEmployeeBirthDate').val(),
"code":$('#editEmployeeCode').val(),
"email":$('#editEmployeeEmail').val(),
"phone":$('#editEmployeePhone').val(),
"idEmployeeType":$('#editEmployeeType').val(),
"contractType":$('#editEmployeeContractType').val()
};
$.ajax({
url: baseUrl + '/api/employee',
type: 'PUT',
dataType: 'json',
data: parameters,
success:function(data){
$('#modalServerResponseSuccess').modal('show');
document.getElementById('serverResponseSuccess').innerHTML = 'The employee ' + data['fullName'] + ' has been updated.';
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}

View File

@@ -0,0 +1,255 @@
/**
* Bootstrapping the starting actions for the module
*/
$(document).ready(function(){
let baseUrl = getbaseUrl();
loadEmployeeTypesForWorkDays();
$('.datepicker').datepicker({
format: "yyyy/mm/dd",
autoclose: true
});
// Not to be edited
$("#hidenEmployeeCodeForWorkDays").hide();
// Setting up bloodhound typeahead
let employeesList = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("name"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
'cache': false,
url: baseUrl + '/api/employee/find',
replace: function(url, uriEncodedQuery) {
return url + '/' + uriEncodedQuery
},
wildcard: '%QUERY',
filter: function (data) {
return data;
}
}
});
employeesList.initialize();
$("#workDaysSearchEmployee").typeahead({
hint: true,
highlight: true,
minLength: 3
},
{
name: "result",
displayKey: "fullName",
source: employeesList.ttAdapter()
}).bind("typeahead:selected", function(obj, datum, name) {
$(this).data("id", datum.code);
loadEmployeeDataForWorkDays(datum.code);
validateEmployeeCanDoOtherRoles(datum.code);
loadSalaryDetails(datum.code);
$('#hidenEmployeeCodeForWorkDaysCode').val(datum.code); // For future reference
});
});
/**
* Loads the the employee types into their select option
*/
function loadEmployeeTypesForWorkDays(){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/types',
type: 'GET',
dataType: 'json',
success:function(data){
$(data).each(function(i,v){
$('#workDaysEmployeeRol').append(
'<option value="' + v.id + '">'+ v.name + '</option>'
);
$('#workDaysEmployeePerformedRol').append(
'<option value="' + v.id + '">'+ v.name + '</option>'
);
});
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
/**
* Searches the employee data by its employee code and loads it
* into the form to be edited and saved
*
* @param code string
*/
function loadEmployeeDataForWorkDays(code){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/code/' + code,
type: 'GET',
dataType: 'json',
success:function(data){
let fullName = data['firstName'] + ' ' + data['middleName'] + ' ' + data['lastName'];
$('#workDaysEmployeeName').val(fullName);
$('#workDaysEmployeeRol').val(data['idEmployeeType']);
$('#workDaysEmployeePerformedRol').val(data['idEmployeeType']);
$('#workDaysEmployeeContractType').val(data['contractType']);
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
/**
* Based on the employee code determines their type to decide if
* they should be able to cover for other roles or not
*
* @param code string
*/
function validateEmployeeCanDoOtherRoles(code){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/type/' + code,
type: 'GET',
dataType: 'json',
success:function(data){
if(data == 3){
$("#workDaysEmployeePerformedRol").prop('disabled', false);
}
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
function loadSalaryDetails(code){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/employee/salary/' + code,
type: 'GET',
dataType: 'json',
success:function(data){
$('#workDaysEmployeeSalaryRaw').val(data['raw']);
$('#workDaysEmployeeSalaryTaxes').val(data['taxes']);
$('#workDaysEmployeeSalaryFinal').val(data['real']);
$('#workDaysEmployeeSalaryVouchers').val(data['vouchers']);
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}
function saveNewWorkDay(){
let baseUrl = getbaseUrl();
let parameters = {
"code":$('#hidenEmployeeCodeForWorkDaysCode').val(),
"idEmployeeTypePerformed":$('#workDaysEmployeePerformedRol').val(),
"deliveries":$('#workDaysEmployeeDeliveries').val(),
"date":$('#workDaysEmployeeWorkedDay').val(),
};
$.ajax({
url: baseUrl + '/api/employee/workday',
type: 'POST',
dataType: 'json',
data: parameters,
success:function(data){
$('#modalServerResponseSuccess').modal('show');
document.getElementById('serverResponseSuccess').innerHTML = data['message'];
loadSalaryDetails($('#hidenEmployeeCodeForWorkDaysCode').val());
},
error:function(x,e) {
let responseText = $.parseJSON(x["responseText"]);
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalServerResponseError').modal('show');
document.getElementById('modalResponseError').innerHTML = responseText['message'];
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modalErrorOther').modal('show');
}
},
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
<?php <?php
namespace App\Application; namespace App\Application;
use Exception;
use phpDocumentor\Reflection\Types\Integer; use phpDocumentor\Reflection\Types\Integer;
class EmployeeApplication{ class EmployeeApplication{
@@ -20,6 +21,8 @@ class EmployeeApplication{
} }
/** /**
* A list of the types of employee used in the system
*
* @return array * @return array
*/ */
function listEmployeeTypes(){ function listEmployeeTypes(){
@@ -54,6 +57,7 @@ class EmployeeApplication{
* @param $email string * @param $email string
* @param $phone string * @param $phone string
* @return integer * @return integer
* @throws Exception
*/ */
function saveNewPerson($firstName, $middleName, $lastName, $birthDate, $email, $phone){ function saveNewPerson($firstName, $middleName, $lastName, $birthDate, $email, $phone){
$this->asserts->isNotEmpty($firstName, "The first name can't be empty."); $this->asserts->isNotEmpty($firstName, "The first name can't be empty.");
@@ -87,6 +91,7 @@ class EmployeeApplication{
* @param $code string * @param $code string
* @param $contractType string * @param $contractType string
* @return mixed * @return mixed
* @throws Exception
*/ */
function savePersonAsEmployee($idEmployeeType, $idPerson, $code, $contractType){ function savePersonAsEmployee($idEmployeeType, $idPerson, $code, $contractType){
$this->asserts->higherThanZero($idEmployeeType, "idEmployeeType must be higher than 0"); $this->asserts->higherThanZero($idEmployeeType, "idEmployeeType must be higher than 0");
@@ -115,6 +120,7 @@ class EmployeeApplication{
/** /**
* @param $requestData object * @param $requestData object
* @return array * @return array
* @throws Exception
*/ */
function saveNewEmployee($requestData){ function saveNewEmployee($requestData){
// Getting and validating the data // Getting and validating the data
@@ -145,7 +151,11 @@ class EmployeeApplication{
$this->asserts->betweenLength($phone, 10, 10, "The phone number must be 10 digits without special characters."); $this->asserts->betweenLength($phone, 10, 10, "The phone number must be 10 digits without special characters.");
$idEmployeeType = $requestData{'idEmployeeType'}; $idEmployeeType = $requestData{'idEmployeeType'};
$this->asserts->higherThanZero($idEmployeeType, 'idEmployeeType must be higher than zero.');
$contractType = $requestData{'contractType'}; $contractType = $requestData{'contractType'};
$this->asserts->isNotEmpty($contractType, "The contract type can't be empty.");
$this->asserts->existInArray($contractType, $this->settings['contractTypes'], 'The contract type is not a valid one.');
// Encrypting the sensitive data // Encrypting the sensitive data
$securedFirstName = $this->cryptographyService->encryptString($firstName); $securedFirstName = $this->cryptographyService->encryptString($firstName);
@@ -229,6 +239,33 @@ class EmployeeApplication{
return $results[0]['id']; return $results[0]['id'];
} }
/**
* @param $code string
* @return integer
*/
function getIdEmployeeByCode($code){
$this->asserts->isNotEmpty($code, "The code can't be empty.");
$stmt = $this->pdo->prepare("SELECT
COALESCE((SELECT
id
FROM
employees
WHERE
code = :code),
0) AS id;
");
$stmt->execute(array(':code' => $code));
$results = $stmt->fetchAll();
if(!$results){
exit($this->databaseSelectQueryErrorMessage);
}
$stmt = null;
return $results[0]['id'];
}
/** /**
* Gets the data associated with the employee * Gets the data associated with the employee
* *
@@ -239,13 +276,16 @@ class EmployeeApplication{
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0"); $this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$stmt = $this->pdo->prepare("SELECT $stmt = $this->pdo->prepare("SELECT
e.id AS idEmployee,
p.id AS idPerson, p.id AS idPerson,
p.firstName, p.firstName,
p.middleName, p.middleName,
IFNULL(p.lastName, '') AS lastName, IFNULL(p.lastName, '') AS lastName,
p.birthDate,
p.email, p.email,
p.phone, p.phone,
e.code, e.code,
e.idEmployeeType,
e.contractType e.contractType
FROM FROM
employees e employees e
@@ -277,6 +317,7 @@ class EmployeeApplication{
$employeeData = $this->getEmployeeDataById($idEmployee); $employeeData = $this->getEmployeeDataById($idEmployee);
$response = array( $response = array(
"idEmployee" => (int)$employeeData['idEmployee'],
"idPerson" => (int)$employeeData['idPerson'], "idPerson" => (int)$employeeData['idPerson'],
"firstName" => $this->cryptographyService->decryptString($employeeData['firstName']), "firstName" => $this->cryptographyService->decryptString($employeeData['firstName']),
"middleName" => $this->cryptographyService->decryptString($employeeData['middleName']), "middleName" => $this->cryptographyService->decryptString($employeeData['middleName']),
@@ -285,9 +326,11 @@ class EmployeeApplication{
? $this->cryptographyService->decryptString($employeeData['lastName']) ? $this->cryptographyService->decryptString($employeeData['lastName'])
: '', : '',
"birthDate" => $employeeData['birthDate'],
"email" => $this->cryptographyService->decryptString($employeeData['email']), "email" => $this->cryptographyService->decryptString($employeeData['email']),
"phone" => $employeeData['phone'], "phone" => $employeeData['phone'],
"code" => $employeeData['code'], "code" => $employeeData['code'],
"idEmployeeType" => $employeeData['idEmployeeType'],
"contractType" => $employeeData['contractType'] "contractType" => $employeeData['contractType']
); );
@@ -302,7 +345,7 @@ class EmployeeApplication{
function getEmployeeDataByCode($code){ function getEmployeeDataByCode($code){
$this->asserts->isNotEmpty($code, "The code can't be empty."); $this->asserts->isNotEmpty($code, "The code can't be empty.");
$idEmployee = $this->getIdEmployeeTypeByCode($code); $idEmployee = $this->getIdEmployeeByCode($code);
return $this->proxyGetEmployeeDataById($idEmployee); return $this->proxyGetEmployeeDataById($idEmployee);
} }
@@ -383,15 +426,12 @@ class EmployeeApplication{
*/ */
function updateEmployeeData($requestData){ function updateEmployeeData($requestData){
// Getting and validating the data // Getting and validating the data
$idEmployee = $requestData['idEmployee'];
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$idPerson = $this->getIdPersonByIdEmployee($idEmployee);
$this->asserts->higherThanZero($idPerson, "idPerson must be higher than 0");
$code = $requestData['code']; $code = $requestData['code'];
$this->asserts->isNotEmpty($code, "The code can't be empty."); $this->asserts->isNotEmpty($code, "The code can't be empty.");
$idEmployee = $this->getIdEmployeeByCode($code);
$idPerson = $this->getIdPersonByIdEmployee($idEmployee);
$firstName = $requestData['firstName']; $firstName = $requestData['firstName'];
$this->asserts->isNotEmpty($firstName, "The first name can't be empty."); $this->asserts->isNotEmpty($firstName, "The first name can't be empty.");
$this->asserts->isString($firstName, "The first name must be a string."); $this->asserts->isString($firstName, "The first name must be a string.");
@@ -421,6 +461,7 @@ class EmployeeApplication{
$contractType = $requestData{'contractType'}; $contractType = $requestData{'contractType'};
$this->asserts->isNotEmpty($contractType, "The contract type can't be empty."); $this->asserts->isNotEmpty($contractType, "The contract type can't be empty.");
$this->asserts->existInArray($contractType, $this->settings['contractTypes'], 'The contract type is not a valid one.');
// Encrypting the sensitive data // Encrypting the sensitive data
$securedFirstName = $this->cryptographyService->encryptString($firstName); $securedFirstName = $this->cryptographyService->encryptString($firstName);
@@ -500,6 +541,9 @@ class EmployeeApplication{
} }
/** /**
* Uses an already existing method to create and array containing the details of
* all currently active employees
*
* @return array * @return array
*/ */
function listAllActiveEmployees(){ function listAllActiveEmployees(){
@@ -508,10 +552,330 @@ class EmployeeApplication{
$result = array(); $result = array();
foreach($ids as $row){ foreach($ids as $row){
$result[] = $this->proxyGetEmployeeDataById($row['id']); $currentEmployee = $this->proxyGetEmployeeDataById($row['id']);
$result[] = array(
'fullName' => $currentEmployee['firstName']." ".
$currentEmployee['middleName']." ".
$currentEmployee['lastName'],
'code' => $currentEmployee['code']
);
} }
return $result; return $result;
} }
/**
* Takes an array of all active employees and filters them by a string, returning
* all sub arrays that contain such string
*
* @param $partialName string
* @return array
*/
function findEmployeeByFullName($partialName){
$fullList = $this->listAllActiveEmployees();
$pattern = '/'.$partialName.'/';
$matches = array_filter($fullList, function($a) use($pattern) {
return preg_grep($pattern, $a);
});
return $matches;
}
/**
* Helper to determine if the date has already been saved as a worked day for
* an employee, so long as it's currently active in the database
*
* @param $idEmployee integer
* @param $date date
* @return integer
* @throws Exception
*/
function checkDateNotUsedWorkDayPerEmployee($idEmployee, $date){
$this->asserts->isNotEmpty($idEmployee, "The code can't be empty.");
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$this->asserts->isNotEmpty($date, "The code can't be empty.");
$stmt = $this->pdo->prepare("SELECT
COALESCE((SELECT
COUNT(*)
FROM
paymentsPerEmployeePerDay
WHERE
date = :date AND idEmployee = :idEmployee
AND status = 'ACTIVE'),
0) AS timesDateFound");
$stmt->execute(array(':date' => $date, ':idEmployee' => $idEmployee));
$results = $stmt->fetchAll();
if(!$results){
throw new Exception('Unable to determine the usage of date for the worked days.');
}
$stmt = null;
return $results[0]['timesDateFound'];
}
/**
* Saves the new worked day for the employee
*
* @param $idEmployee integer
* @param $date date
* @param $baseAmount double
* @param $bonusTime double
* @param $deliveries double
* @return integer
* @throws Exception
*/
function saveWorkedDay($idEmployee, $date, $baseAmount, $bonusTime, $deliveries){
$this->asserts->isNotEmpty($idEmployee, "The idEmployee can't be empty.");
$this->asserts->isNotEmpty($date, "The date can't be empty.");
$this->asserts->isNotEmpty($baseAmount, "The base payment per day can't be empty.");
$this->asserts->isNotEmpty($bonusTime, "The bonus per worked hours can't be empty.");
$this->asserts->isNotEmpty($deliveries, "The payment for deliveries can't be empty.");
try {
$stmt = $this->pdo->prepare("INSERT INTO paymentsPerEmployeePerDay
(idEmployee, date, baseAmount, bonusTime, deliveries)
VALUES (:idEmployee, :date, :baseAmount, :bonusTime, :deliveries)");
$this->pdo->beginTransaction();
$stmt->execute(array(':idEmployee' => $idEmployee, ':date' => $date, ':baseAmount' => $baseAmount,
':bonusTime' => $bonusTime, ':deliveries' => $deliveries));
$id = $this->pdo->lastInsertId();
$this->pdo->commit();
return $id;
$stmt = null;
} catch( PDOExecption $e ) {
$this->pdo->rollback();
throw new Exception('There was an error while trying to save the worked day.');
}
}
/**
* Takes the data from the front end for the new worked day for a
* employee and saves it
*
* @param $requestData object
* @return array
* @throws Exception
*/
function SaveNewWorkDay($requestData){
$code = $requestData['code'];
$this->asserts->isNotEmpty($code, "The code can't be empty.");
$idEmployee = $this->getIdEmployeeByCode($code);
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$idEmployeeType = $this->getIdEmployeeTypeByCode($code);
$this->asserts->higherThanZero($idEmployeeType, "idEmployeeType must be higher than 0");
$idEmployeeTypePerformed = $requestData['idEmployeeTypePerformed'];
$this->asserts->isNotEmpty($idEmployeeTypePerformed, "The performed rol must be provided.");
$this->asserts->higherThanZero($idEmployeeTypePerformed, "idEmployeeTypePerformed must be higher than 0");
$deliveries = $requestData['deliveries'];
$this->asserts->isNotEmpty($deliveries, "The number of deliveries cannot be empty or 0.");
$date = $requestData['date'];
$this->asserts->isNotEmpty($date, "The worked date cannot be empty.");
if($this->checkDateNotUsedWorkDayPerEmployee($idEmployee, $date) > 0){
throw new Exception("This date has already been saved as a worked day.");
}
// The emplpoyee can't take that rol
if($idEmployeeType != 3 and $idEmployeeType != $idEmployeeTypePerformed){
throw new Exception("The performed rol can't be done by this type of employee.");
}
// If we're working on a different month
$this->asserts->datesHaveSameMonth($date, date('Y-m-d'), "Work days can only be registered within the same month.");
$baseAmountPaid = $this->settings['hoursPerWorkDay'] * $this->settings['paymentPerHour'];
// Getting setting data based on employee type that was performed
switch ($idEmployeeTypePerformed) {
case 1:
$perHourBonus = $this->settings['perHourBonusDriver'];
break;
case 2:
$perHourBonus = $this->settings['perHourBonusLoader'];
break;
case 3:
$perHourBonus = $this->settings['perHourBonusAux'];
break;
}
$bonusTime = $perHourBonus * $this->settings['hoursPerWorkDay'];
$bonusDeliveries = $deliveries * $this->settings['bonusPerDelivery'];
$this->saveWorkedDay($idEmployee, $date, $baseAmountPaid, $bonusTime, $bonusDeliveries);
return array('status' => 'success', 'message' => 'The worked day has been saved.', 'data' => $requestData);
}
/**
* The number of days the employee has worked for a given year and month only
* taking into accout the active ones
*
* @param $idEmployee integer
* @param $year integer
* @param $month integer
* @return integer
* @throws Exception
*/
function findNumberWorkedOfDaysByEmployeeAndDate($idEmployee, $year, $month){
$this->asserts->isNotEmpty($idEmployee, "The code can't be empty.");
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$this->asserts->higherThanZero($year, "year must be higher than 0");
$this->asserts->higherThanZero($month, "month must be higher than 0");
$stmt = $this->pdo->prepare("SELECT
COALESCE((SELECT
COUNT(*)
FROM
paymentsPerEmployeePerDay
WHERE
idEmployee = :idEmployee
AND YEAR(date) = :year
AND MONTH(date) = :month
AND status = 'ACTIVE'),
0) AS workedDays");
$stmt->execute(array(':idEmployee' => $idEmployee, ':year' => $year, ':month' => $month));
$results = $stmt->fetchAll();
if(!$results){
throw new Exception('Unable to determine the amount of worked days.');
}
$stmt = null;
return $results[0]['workedDays'];
}
/**
* A list of the data contained from all the days the employee has worked
* for the given month and year
*
* @param $idEmployee integer
* @param $year integer
* @param $month integer
* @return array
* @throws Exception
*/
function getDataWorkedDaysByEmployee($idEmployee, $year, $month){
$stmt = $this->pdo->prepare("SELECT
baseAmount, bonusTime, deliveries
FROM
paymentsPerEmployeePerDay
WHERE
idEmployee = :idEmployee AND
YEAR(date) = :year
AND MONTH(date) = :month
AND status = 'ACTIVE'");
$stmt->execute(array(':idEmployee' => $idEmployee, ':year' => $year, ':month' => $month));
$results = $stmt->fetchAll();
if(!$results){
throw new Exception("No data of the worked days could be found.");
}
$stmt = null;
return $results;
}
/**
* @param $idEmployee integer
* @return string
* @throws Exception
*/
function getContractTypeByEmployee($idEmployee){
$this->asserts->isNotEmpty($idEmployee, "The code can't be empty.");
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$stmt = $this->pdo->prepare("SELECT
contractType
FROM
employees
WHERE
id = :idEmployee");
$stmt->execute(array(':idEmployee' => $idEmployee));
$results = $stmt->fetchAll();
if(!$results){
throw new Exception("The employee wasn't found.");
}
$stmt = null;
return $results[0]['contractType'];
}
/**
* Gets all the worked days for an employee and determines how much they're
* getting paid
*
* Will only work for the current month
*
* @param $code string
* @return array
* @throws Exception
*/
function calculateSalaryByCode($code){
$this->asserts->isNotEmpty($code, "The code can't be empty.");
$idEmployee = $this->getIdEmployeeByCode($code);
$this->asserts->higherThanZero($idEmployee, "idEmployee must be higher than 0");
$salary = array(
'raw' => 0,
'taxes' => 0,
'real' => 0,
'vouchers' => 0
);
// No worked days found
if($this->findNumberWorkedOfDaysByEmployeeAndDate($idEmployee, date('Y'), date('m')) <= 0){
return $salary;
}
$dataWorkedDays = $this->getDataWorkedDaysByEmployee($idEmployee, date('Y'), date('m'));
$monthlyPayment = 0;
foreach($dataWorkedDays as $row){
$monthlyPayment = $monthlyPayment + $row['baseAmount'] + $row['bonusTime'] + $row['deliveries'];
}
$salary['raw'] = $monthlyPayment;
if($monthlyPayment >= $this->settings['amountForExtraTaxes']){
$this->settings['taxesAddUp']
? $taxes = $monthlyPayment * ($this->settings['baseIsr'] + $this->settings['extraIsr'])
: $taxes = ($monthlyPayment * $this->settings['baseIsr']) + (($monthlyPayment * $this->settings['baseIsr']) * $this->settings['extraIsr']);
}else{
$taxes = $monthlyPayment * $this->settings['baseIsr'];
}
$salary['taxes'] = $taxes;
$salary['real'] = $monthlyPayment - $taxes;
$contractType = $this->getContractTypeByEmployee($idEmployee);
if($contractType == 'INTERNO'){
$vouchers = $monthlyPayment * $this->settings['percentOfPaymentForVouchers'];
}elseif ($contractType == 'EXTERNO'){
$this->settings['vouchersForAllContractTypes']
? $vouchers = $monthlyPayment * $this->settings['percentOfPaymentForVouchers']
: $vouchers = 0;
}
$salary['vouchers'] = $vouchers;
return $salary;
}
} }
?> ?>

View File

@@ -41,10 +41,12 @@ $app->get('/api/employee/types', function (Request $request, Response $response,
->write(json_encode($this->employeeApplication->listEmployeeTypes())); ->write(json_encode($this->employeeApplication->listEmployeeTypes()));
}); });
$app->get('/api/employee/all', function (Request $request, Response $response, array $args) { $app->get('/api/employee/find/{partialName}', function (Request $request, Response $response, array $args) {
$partialName = $args['partialName'];
return $response->withStatus(200) return $response->withStatus(200)
->withHeader('Content-Type', 'application/json') ->withHeader('Content-Type', 'application/json')
->write(json_encode($this->employeeApplication->listAllActiveEmployees())); ->write(json_encode($this->employeeApplication->findEmployeeByFullName($partialName)));
}); });
$app->post('/api/employee', function ($request, $response) { $app->post('/api/employee', function ($request, $response) {
@@ -93,4 +95,20 @@ $app->get('/api/employee/code/{code}', function (Request $request, Response $res
return $response->withStatus(200) return $response->withStatus(200)
->withHeader('Content-Type', 'application/json') ->withHeader('Content-Type', 'application/json')
->write(json_encode($this->employeeApplication->getEmployeeDataByCode($code))); ->write(json_encode($this->employeeApplication->getEmployeeDataByCode($code)));
});
$app->post('/api/employee/workday', function ($request, $response) {
$requestData = $request->getParsedBody();
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($this->employeeApplication->SaveNewWorkDay($requestData)));
});
$app->get('/api/employee/salary/{code}', function (Request $request, Response $response, array $args) {
$code = $args['code'];
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json')
->write(json_encode($this->employeeApplication->calculateSalaryByCode($code)));
}); });

View File

@@ -69,5 +69,31 @@ class Asserts{
throw new Exception($errorMessage); throw new Exception($errorMessage);
} }
} }
/**
* @param $string string
* @param $array array
* @param $errorMessage string
* @throws Exception
*/
function existInArray($string, $array, $errorMessage){
if(!in_array($string, $array)){
throw new Exception($errorMessage);
}
}
/**
* Compares two dates to dertermine if they have the same month
*
* @param $firstDate date
* @param $secondDate date
* @param $errorMessage string
* @throws Exception
*/
function datesHaveSameMonth($firstDate, $secondDate, $errorMessage){
if (date("m",strtotime($firstDate)) != date("m",strtotime($secondDate))){
throw new Exception($errorMessage);
}
}
} }
?> ?>

View File

@@ -45,6 +45,19 @@ return [
// Employee settings // Employee settings
'employee' => [ 'employee' => [
'codeLength' => '3', 'codeLength' => '3',
'contractTypes' => array('INTERNO', 'EXTERNO'),
'hoursPerWorkDay' => 8,
'paymentPerHour' => 30,
'bonusPerDelivery' => 5,
'perHourBonusDriver' => 10,
'perHourBonusLoader' => 5,
'perHourBonusAux' => 0,
'baseIsr' => .09,
'extraIsr' => .03,
'taxesAddUp' => true, // If true this will be total/(9 + 3) else they're subtracted separately
'amountForExtraTaxes' => 16000,
'vouchersForAllContractTypes' => false, // Outsourced personal won't get vouchers
'percentOfPaymentForVouchers' => .04,
], ],
], ],
]; ];

View File

@@ -73,3 +73,19 @@ CREATE TABLE IF NOT EXISTS `employees` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE (`code`) UNIQUE (`code`)
); );
DROP TABLE IF EXISTS paymentsPerEmployeePerDay;
CREATE TABLE IF NOT EXISTS `paymentsPerEmployeePerDay` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`idEmployee` INT UNSIGNED NOT NULL comment 'The employee to who this payment will be made',
`date` DATE NOT NULL DEFAULT '1900-01-01' comment 'Date of the worked day',
`baseAmount` DOUBLE(10,2) NOT NULL DEFAULT 0.0 comment 'Amount paid for the hours worked',
`bonusTime` DOUBLE(10,2) NOT NULL DEFAULT 0.0 comment 'Bonus paid for the hours worked',
`deliveries` DOUBLE(10,2) NOT NULL DEFAULT 0.0 comment 'Bonus for the number of deliveries',
`status` ENUM('ACTIVE', 'INACTIVE') NOT NULL DEFAULT 'ACTIVE',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP comment 'The date on which the registry was created',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment 'The date of the last time the row was modified',
PRIMARY KEY (`id`),
FOREIGN KEY (idEmployee) REFERENCES employees(id),
UNIQUE (`idEmployee`, `date`, `status`)
);