Compare commits

..

39 Commits

Author SHA1 Message Date
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
abd8168dbf [add] Asserting email type 2018-08-12 17:15:39 -06:00
79059fb91b [mod] Updated html and css references 2018-08-12 16:59:46 -06:00
1b2484fbf2 [fix] Phone number length in database 2018-08-12 16:27:05 -06:00
168a6a352e [add] Displaying data post save 2018-08-12 16:25:23 -06:00
8185a42331 [add] Saving new employee 2018-08-12 15:54:56 -06:00
64a6ddafb5 [add] Datepicker 2018-08-12 15:38:09 -06:00
54ef088fe0 [add] New employee form layout 2018-08-12 14:39:47 -06:00
b829f09330 [fix] Reference to view body 2018-08-12 11:36:17 -06:00
b03d152f11 [add] Loading views 2018-08-12 11:32:48 -06:00
0ec20a4c67 [add] Logout uses generic error messages
Refactored some messages from the generic modals
2018-08-12 10:39:44 -06:00
1605b1cea3 Merge pull request #17 from PootisPenserHere/interactionBetweenLoginAndPanel
Interaction between login and panel
2018-08-12 10:08:54 -06:00
d4fadf08bc [add] Logout
Also made general fixes to the css
2018-08-12 10:03:25 -06:00
de84da4482 [add] Mapping enter key 2018-08-12 09:13:00 -06:00
697d0fe769 [mod] getBaseUrl moved to its own file 2018-08-12 09:07:48 -06:00
cb5d30b4e0 [add] Verifying session 2018-08-12 08:51:22 -06:00
6c91cad46c Merge pull request #16 from PootisPenserHere/qualityChangesToDocker
Quality changes to docker
2018-08-11 20:07:07 -06:00
ccd9e10351 Merge pull request #15 from PootisPenserHere/landingPage
Landing page
2018-08-11 20:06:13 -06:00
30f755c0b2 [fix] Misleading error when login 2018-08-11 20:03:28 -06:00
231e7fe2e6 [add] Access config 2018-08-12 01:43:37 +00:00
f820a22a4f [add] Volumes directory 2018-08-12 01:25:11 +00:00
0cdfd21fa2 [mod] Config files moved to a directory 2018-08-12 01:06:40 +00:00
fee3db486f [add] Composer decoupled from prod build 2018-08-12 00:58:12 +00:00
87181696e1 [add] Looks of the dockerfile 2018-08-12 00:49:03 +00:00
8b22c0db9c [add] Composer compileed in multi stagre 2018-08-12 00:38:39 +00:00
7feb3a6f5d [add] Landing page skeleton 2018-08-10 01:31:25 -06:00
18ee0ad333 [add] Downloading composer dependencies 2018-08-10 06:53:13 +00:00
e5d90bc32d Merge pull request #14 from PootisPenserHere/genericAsserts
Generic asserts
2018-08-09 23:29:58 -06:00
4928481f72 [add] Empty log file with permisions 2018-08-10 03:51:17 +00:00
Jose Pablo Domingo Aramburo Sanchez
2d11218076 [fix] php volume 2018-08-09 13:42:13 -06:00
59a4d6e4a5 Merge pull request #13 from PootisPenserHere/loginFront
Login front
2018-08-09 02:35:11 -06:00
31 changed files with 3694 additions and 59 deletions

View File

@@ -1 +1,2 @@
Options -Indexes Options -Indexes
Deny from all

View File

@@ -1,10 +1,29 @@
# Stage 1 - the build process
FROM composer:1.7.1 as build-deps
ENV COMPOSER_ALLOW_SUPERUSER 1
WORKDIR /root
COPY . .
RUN composer install
RUN composer test
# Stage 2 - the production environment
FROM ubuntu:16.04 FROM ubuntu:16.04
# Updating
RUN apt-get -y update && apt-get -y upgrade RUN apt-get -y update && apt-get -y upgrade
# Installing php, apache and supplementary software RUN apt-get -y install apache2 \
RUN apt-get -y install apache2 php7.0 libapache2-mod-php7.0 php7.0-cli php7.0-common php7.0-mbstring php7.0-gd php7.0-intl php7.0-xml php7.0-mysql php7.0-mcrypt php7.0-zip curl git unzip composer php7.0 \
libapache2-mod-php7.0 \
php7.0-cli \
php7.0-common \
php7.0-mbstring \
php7.0-gd \
php7.0-intl \
php7.0-xml \
php7.0-mysql \
php7.0-mcrypt
# Enable apache mods # Enable apache mods
RUN a2enmod php7.0 RUN a2enmod php7.0
@@ -20,24 +39,14 @@ ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2 ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2 ENV APACHE_LOCK_DIR /var/lock/apache2
# Expose apache
EXPOSE 80
# Copy this repo into place.
ADD . /var/www/site
WORKDIR /var/www/site WORKDIR /var/www/site
COPY --from=build-deps /root .
# Testing permisions RUN touch logs/app.log
RUN chmod 777 -R . RUN chmod 777 logs/app.log
# Installing dependencies # Update the default apache site
RUN composer install ADD docker/apache-config.conf /etc/apache2/sites-enabled/000-default.conf
# Unit tests # By default start up apache in the foreground
RUN composer test
# Update the default apache site with the config we created.
ADD apache-config.conf /etc/apache2/sites-enabled/000-default.conf
# By default start up apache in the foreground, override with /bin/bash for interative
CMD /usr/sbin/apache2ctl -D FOREGROUND CMD /usr/sbin/apache2ctl -D FOREGROUND

0
api-payroll/logs/app.log Executable file
View File

View File

@@ -1,3 +1,5 @@
allow from all
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
RewriteEngine On RewriteEngine On

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,243 @@
body {
background-color: #e3e3e3;
color: #000;
}
.datepicker{
color: black;
}
#newViewBody{
top:17%;
left:1%;
width:98%;
float:left;
}
#navigation_spot{
margin: 0;
padding: 0;
}
#footer {
}
#newViewBody .modal-body{
color: #000;
border:none;
}
#newViewBody .panel-default{
border: 3px solid #4A89A5;
border-radius: 5px;
}
#newViewBody .panel > .panel-heading {
background-image: none;
background-color: #4A89A5;
color: white;
border-radius: 0;
}
#newViewBody .btn-default{
border: 2px solid #62655F;
background: #F9DFAF;
}
#newViewBody .btn-default:hover{
border: 2px solid #62655F;
background: #F9DFAF;
}
#newViewBody .alert-success{
background: #C6E97C;
}
.modalHeaderError{
background-color: #d9534f;
}
.modalHeaderSuccess{
background-color: #5bc0de;
}
.metro{
width:auto;
height:auto;
}
.metroBox{
margin: 0 auto;
width:100%;
padding: 0;
height:auto;
display:table;
overflow: hidden;
}
.metroBox h3{
margin-bottom: 0;
padding-bottom: 0;
}
.metroBox a{
text-decoration: none;
color: #fff;
}
.boxElement{
color: #fff;
height:210px;
width: 318px;
float:left;
margin:0 5px 5px 0;
padding:0 1% 0 1%;
}
.boxElement:hover{
color: #fff;
background: #483D8B;
text-decoration: none;
}
.amarelo{
background:#f4c20d;
}
.vermelho{
background:#da542d;
}
.azul{
background:#009bad;
}
.azulFuerte{
background:#5636b0;
}
.verde{
background-color: #009f00;
}
.violet{
background-color: #a400ab;
}
.iconPanel{
font-size: 130px;
}
@media (max-width: 310px){
.boxElement{
width: 245px;
}
}
@media (min-width: 311px) and (max-width: 353px){
.boxElement{
width: 265px;
}
}
@media (min-width: 354px) and (max-width: 365px){
.boxElement{
width: 320px;
}
}
@media (min-width: 366px) and (max-width: 520px){
.boxElement{
width: 320px;
}
}
@media (min-width: 521px) and (max-width: 549px){
.boxElement{
width: 235px;
}
}
@media (min-width: 550px) and (max-width: 590px){
.boxElement{
width: 250px;
}
}
@media (min-width: 591px) and (max-width: 610px){
.boxElement{
width: 265px;
}
}
@media (min-width: 611px) and (max-width: 630px){
.boxElement{
width: 275px;
}
}
@media (min-width: 631px) and (max-width: 655px){
.boxElement{
width: 280px;
}
}
@media (min-width: 656px) and (max-width: 699px){
.boxElement{
width: 300px;
}
}
@media (min-width: 700px) and (max-width: 739px){
.boxElement{
width: 320px;
}
}
@media (min-width: 740px) and (max-width: 769px){
.boxElement{
width: 340px;
}
}
@media (min-width: 770px) and (max-width: 1230px){
.boxElement{
width: 280px;
}
}
.formato_texto_custom{
width: 97%;
float: left;
border: 1px solid #222;
padding: 1%;
margin: .5%;
}
.cliente_muestra_producto{
width: 96%;
padding: 1%;
margin: 0 1% 2% 1%;
}
textarea{
resize: none;
}
#custom-bootstrap-menu.navbar-default .navbar-brand {
color: rgba(255, 255, 255, 1);
}
#custom-bootstrap-menu.navbar-default {
font-size: 14px;
background-color: rgba(27, 35, 78, 1);
border-width: 1px;
border-radius: 4px;
}
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a {
color: rgba(255, 255, 255, 1);
background-color: rgba(27, 35, 78, 1);
}
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a:hover,
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a:focus {
color: rgba(106, 171, 232, 1);
background-color: rgba(27, 35, 78, 1);
}
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a,
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a:hover,
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a:focus {
color: rgba(255, 255, 255, 1);
background-color: rgba(27, 35, 78, 1);
}
#custom-bootstrap-menu.navbar-default .navbar-toggle {
border-color: #1b234e;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle:hover,
#custom-bootstrap-menu.navbar-default .navbar-toggle:focus {
background-color: #1b234e;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle .icon-bar {
background-color: #1b234e;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle:hover .icon-bar,
#custom-bootstrap-menu.navbar-default .navbar-toggle:focus .icon-bar {
background-color: #1b234e;
}

View File

@@ -18,7 +18,7 @@ body {
padding: 20px; padding: 20px;
background: #fff; background: #fff;
border-radius: 5px; border-radius: 5px;
border-top: 5px solid #bdb035; border-top: 5px solid #5bc0de;
margin: 0 auto; margin: 0 auto;
} }
.login-block h1 { .login-block h1 {
@@ -58,15 +58,15 @@ body {
background-size: 16px 80px; background-size: 16px 80px;
} }
.login-block input:active, .login-block input:focus { .login-block input:active, .login-block input:focus {
border: 1px solid #bdb035; border: 1px solid #5bc0de;
} }
.login-block #loginButon { .login-block #loginButon {
width: 100%; width: 100%;
height: 40px; height: 40px;
background: #bdb035; background: #009bad;
box-sizing: border-box; box-sizing: border-box;
border-radius: 5px; border-radius: 5px;
border: 1px solid #6d661c; border: 1px solid #000;
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
@@ -75,7 +75,7 @@ body {
outline: none; outline: none;
cursor: pointer; cursor: pointer;
} }
.login-block button:hover {
background: #c7b935; #modalLoginErrorHeader{
border: 1px solid #6d661c; background-color: #d9534f;
} }

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

@@ -0,0 +1,232 @@
<?php
session_start();
if(!isset($_SESSION['userName'])){
header("Location: ./login.php");
exit();
}
?>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="../css/bootstrap.min.css">
<!-- jQuery library -->
<script src="../js/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="../js/bootstrap.min.js"></script>
<body>
<div class="col-md-12" id="navigation_spot">
<!-- NavBar-->
<div id="custom-bootstrap-menu" class="navbar navbar-default " role="navigation">
<div class="container-fluid">
<div class="navbar-header"><a class="navbar-brand" href="#"></a>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-menubuilder"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse navbar-menubuilder">
<ul class="nav navbar-nav navbar-left" id="nevatation-options">
<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>
<ul class="dropdown-menu">
<li><a href="#" data-nav_accion="newEmployee.php"> New employee</a></li>
<li><a href="#" data-nav_accion="editEmployee.php"> Modify employee</a></li>
</ul>
</li>
<li>
<a href="#" onclick="loadView();"><span class="glyphicon glyphicon-tasks"></span> Management</a>
</li>
<li>
<a href="#" onclick="loadView();"><span class="glyphicon glyphicon-wrench"></span> Change password</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#" onclick="logout();"><span class="fa fa-fw fa-power-off"></span> logout</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="col-md-12" id="newViewBody"></div>
<!--
=================================================================================
Modals for errors encountered by ajax
=================================================================================
-->
<div id="modalErrorInternetConnection" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>Please verify your internet connection and try again.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalError404" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>Unable to find the requested url in the sever.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalError500" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>The server has encountered an internal error, please try again later.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalErrorParsererror" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>The response from the sever wasn't a proper JSON format</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalErrorTimeout" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>The request timeout, please try again or verify your connection.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalErrorOther" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p>An unknown error occurred.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<!--
=================================================================================
Generic response modals
=================================================================================
-->
<div id="modalServerResponseError" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderError">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">An error has occurred</h4>
</div>
<div class="modal-body">
<p id="modalResponseError"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<div id="modalServerResponseSuccess" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header modalHeaderSuccess" id="modalHeaderServerResponseSuccess">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Success</h4>
</div>
<div class="modal-body">
<p id="serverResponseSuccess"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
</body>
<script src="../js/getBaseUrl.js"></script>
<script src="../js/landing.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/landing.css" rel="stylesheet">

View File

@@ -1,3 +1,12 @@
<?php
session_start();
if(isset($_SESSION['userName'])){
header("Location: ./landing.php");
exit();
}
?>
<!-- Latest compiled and minified CSS --> <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="../css/bootstrap.min.css"> <link rel="stylesheet" href="../css/bootstrap.min.css">
@@ -41,4 +50,5 @@
</div> </div>
<script src="../js/login.js"></script> <script src="../js/login.js"></script>
<script src="../js/getBaseUrl.js"></script>
<link href="../css/login.css" rel="stylesheet"> <link href="../css/login.css" rel="stylesheet">

View File

@@ -0,0 +1,93 @@
<script src="../js/newEmployee.js"></script>
<script src="../js/getBaseUrl.js"></script>
<form class="form-horizontal" id="newEmployeeForm">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">New employee</h3>
</div>
<div class="panel-body">
<div class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="newEmployeeFirstName">First name</label>
<div class="col-md-5">
<input id="newEmployeeFirstName" name="newEmployeeFirstName" 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="newEmployeeMiddleName">Middle name</label>
<div class="col-md-5">
<input id="newEmployeeMiddleName" name="newEmployeeMiddleName" 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="newEmployeeLastName">Last name</label>
<div class="col-md-5">
<input id="newEmployeeLastName" name="newEmployeeLastName" 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="newEmployeeBirthDate">Birth date</label>
<div class="col-md-5">
<input id="newEmployeeBirthDate" name="newEmployeeBirthDate" type="text" class="form-control input-md datepicker">
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="newEmployeeEmail">Email</label>
<div class="col-md-5">
<input id="newEmployeeEmail" name="newEmployeeEmail" 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="newEmployeePhone">Phone</label>
<div class="col-md-5">
<input id="newEmployeePhone" name="newEmployeePhone" 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="newEmployeeType">Rol</label>
<div class="col-md-5">
<select class="form-control input-md" name="newEmployeeType" id="newEmployeeType">
<option>Employee type</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<label class="col-md-4 control-label" for="NewEmpployyContractType">Contract type</label>
<div class="col-md-5">
<select class="form-control input-md" name="NewEmpployyContractType" id="NewEmpployyContractType">
<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="saveNewEmployee();">Create</a>
</div>
</div>
</div>
</div>
</div>
</form>

File diff suppressed because one or more lines are too long

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 enmployee 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,10 @@
/**
* Returns the entry point url for the system, this url will be used
* to access both the api and the static resources
*
* @returns {string}
*/
function getbaseUrl(){
var url = window.location.href;
return url.substring(0, url.indexOf('/html/'));
}

View File

@@ -0,0 +1,77 @@
/**
* Destorys the session for the current user and redirects
* back to the login form
*/
function logout() {
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/api/session/logout',
type: 'GET',
dataType: 'json',
success:function(data){
window.location.replace(baseUrl + '/html/login.php');
},
error:function(x,e) {
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalError500').modal('show');
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modal_error_otro').modal('show');
}
},
});
}
/**
* Entry point for loading elements from the navatation var, this functuion
* will filter the junk clicks that have landed in a dropdown menu and pass
* only the ones containing an action to the actual view loader
*/
$('#nevatation-options li a').click(function(){
let view = $(this).data('nav_accion');
if (view != "#" && view != undefined) {
loadView(view);
}
});
/**
* Will fetch the html of the desired view and load it into the landing page
*
* @param requestedView string
*/
function loadView(requestedView){
let baseUrl = getbaseUrl();
$.ajax({
url: baseUrl + '/html/' + requestedView,
type: 'get',
success:function(data){
$("#newViewBody").hide().html(data).show('slow');
},
error:function(x,e) {
if (x.status==0) {
$('#modalErrorInternetConnection').modal('show');
} else if(x.status==404) {
$('#modalError404').modal('show');
} else if(x.status==500) {
$('#modalError500').modal('show');
} else if(e=='parsererror') {
$('#modalErrorParsererror').modal('show');
} else if(e=='timeout'){
$('#modalErrorTimeout').modal('show');
} else {
$('#modal_error_otro').modal('show');
}
},
});
}

View File

@@ -1,24 +1,37 @@
function getbaseUrl(uriPath){ /**
var url = window.location.href; * Maps the enter key to the login action
return url.substring(0, url.indexOf(uriPath)); */
} $(document).keypress(function(e) {
if(e.which == 13) {
processLogin();
}
});
/**
* Takes the input from the username and password fields and send theem to the backend
* to be validated
*
* The response from the api will contain a status that will determine if the login was
* successful or not and a message that will contain feedback which can be used to
* display errors to the user
*/
function processLogin() { function processLogin() {
console.log(getbaseUrl('html/')); let baseUrl = getbaseUrl();
var parametros = {
let parameters = {
"userName":$('#userName').val(), "userName":$('#userName').val(),
"password":$('#password').val() "password":$('#password').val()
}; };
$.ajax({ $.ajax({
url: getbaseUrl('/html/') + '/index.php/api/session/login', url: baseUrl + '/api/session/login',
type: 'POST', type: 'POST',
dataType: 'json', dataType: 'json',
data: parametros, data: parameters,
success:function(data){ success:function(data){
console.log(JSON.stringify(data));
if(data["status"] == "success"){ if(data["status"] == "success"){
redirect("http://stackoverflow.com"); window.location.replace(baseUrl + '/html/landing.php');
}else if(data["status"] == "success" || (data["status"] === undefined)){ }else if(data["status"] == "success" || (data["status"] === undefined)){
$('#modalLoginError').modal('show'); $('#modalLoginError').modal('show');
document.getElementById('modalLoginErrorBody').innerHTML = "The server didn't respond in time, please try again or refresh this page."; document.getElementById('modalLoginErrorBody').innerHTML = "The server didn't respond in time, please try again or refresh this page.";
@@ -31,8 +44,4 @@ console.log(getbaseUrl('html/'));
} }
}, },
}); });
}
function redirect(url){
window.location.replace(url);
} }

View File

@@ -0,0 +1,94 @@
/**
* Bootstrapping the starting actions for the module
*/
$(document).ready(function(){
loadEmployeeTypes();
$('.datepicker').datepicker({
format: "yyyy/mm/dd",
autoclose: true
});
});
/**
* Loads the the enmployee 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){
$('#newEmployeeType').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');
}
},
});
}
function saveNewEmployee(){
let baseUrl = getbaseUrl();
let parameters = {
"firstName":$('#newEmployeeFirstName').val(),
"middleName":$('#newEmployeeMiddleName').val(),
"lastName":$('#newEmployeeLastName').val(),
"birthDate":$('#newEmployeeBirthDate').val(),
"email":$('#newEmployeeEmail').val(),
"phone":$('#newEmployeePhone').val(),
"idEmployeeType":$('#newEmployeeType').val(),
"contractType":$('#NewEmpployyContractType').val()
};
$.ajax({
url: baseUrl + '/api/employee',
type: 'POST',
dataType: 'json',
data: parameters,
success:function(data){
$('#modalServerResponseSuccess').modal('show');
document.getElementById('serverResponseSuccess').innerHTML = 'The employee ' + data['fullName'] + ' has been created with the code ' + data['employeeCode'];
},
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

@@ -138,13 +138,18 @@ class EmployeeApplication{
$email = $requestData['email']; $email = $requestData['email'];
$this->asserts->isNotEmpty($email, "The email can't be empty."); $this->asserts->isNotEmpty($email, "The email can't be empty.");
$this->asserts->betweenLength($email, 1, 100, "The middle name must have a length between 1 and 100 characters."); $this->asserts->betweenLength($email, 1, 100, "The middle name must have a length between 1 and 100 characters.");
$this->asserts->isEmail($email, "The email isn't in a correct format");
$phone = $requestData['phone']; $phone = $requestData['phone'];
$this->asserts->isNotEmpty($phone, "The phone number can't be empty."); $this->asserts->isNotEmpty($phone, "The phone number can't be empty.");
$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);
@@ -228,6 +233,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
* *
@@ -238,13 +270,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
@@ -276,6 +311,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']),
@@ -284,9 +320,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']
); );
@@ -301,7 +339,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);
} }
@@ -382,15 +420,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.");
@@ -409,6 +444,7 @@ class EmployeeApplication{
$email = $requestData['email']; $email = $requestData['email'];
$this->asserts->isNotEmpty($email, "The email can't be empty."); $this->asserts->isNotEmpty($email, "The email can't be empty.");
$this->asserts->betweenLength($email, 1, 100, "The middle name must have a length between 1 and 100 characters."); $this->asserts->betweenLength($email, 1, 100, "The middle name must have a length between 1 and 100 characters.");
$this->asserts->isEmail($email, "The email isn't in a correct format");
$phone = $requestData['phone']; $phone = $requestData['phone'];
$this->asserts->isNotEmpty($phone, "The phone number can't be empty."); $this->asserts->isNotEmpty($phone, "The phone number can't be empty.");
@@ -419,6 +455,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);
@@ -498,6 +535,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(){
@@ -506,10 +546,36 @@ 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;
}
} }
?> ?>

View File

@@ -41,6 +41,7 @@ class SessionApplication{
/** /**
* @param $userName string * @param $userName string
* @return mixed * @return mixed
* @throws Exception
*/ */
function getPassword($userName){ function getPassword($userName){
$this->asserts->isNotEmpty($userName, "The username can't be empty"); $this->asserts->isNotEmpty($userName, "The username can't be empty");
@@ -51,7 +52,7 @@ class SessionApplication{
$stmt->execute(array(':userName' => $userName)); $stmt->execute(array(':userName' => $userName));
$results = $stmt->fetchAll(); $results = $stmt->fetchAll();
if(!$results){ if(!$results){
exit($this->databaseSelectQueryErrorMessage); throw new Exception('The user or password didnt match, please try again.');
} }
$stmt = null; $stmt = null;
return $results[0]['password']; return $results[0]['password'];
@@ -116,12 +117,12 @@ class SessionApplication{
} }
/** /**
* @return string * @return array
*/ */
function destroySession(){ function destroySession(){
session_destroy(); session_destroy();
return "Sucessfully logged out."; return array('status' => 'success', 'message' => 'Successfully logged out.');
} }
} }
?> ?>

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) {

View File

@@ -56,5 +56,30 @@ class Asserts{
throw new Exception($errorMessage); throw new Exception($errorMessage);
} }
} }
/**
* Compares a string against a regex to determine if it's an email
*
* @param $string string
* @param $errorMessage string
* @throws Exception
*/
function isEmail($string, $errorMessage){
if(!filter_var($string, FILTER_VALIDATE_EMAIL)){
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);
}
}
} }
?> ?>

View File

@@ -45,6 +45,7 @@ return [
// Employee settings // Employee settings
'employee' => [ 'employee' => [
'codeLength' => '3', 'codeLength' => '3',
'contractTypes' => array('INTERNO', 'EXTERNO'),
], ],
], ],
]; ];

View File

@@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS `persons` (
`lastName` varbinary(500) comment 'The last name of the person', `lastName` varbinary(500) comment 'The last name of the person',
`birthDate` DATE NOT NULL DEFAULT '1900-01-01' comment 'Date of birth of the person', `birthDate` DATE NOT NULL DEFAULT '1900-01-01' comment 'Date of birth of the person',
`email` varbinary(500) NOT NULL comment 'The email adress of the person', `email` varbinary(500) NOT NULL comment 'The email adress of the person',
`phone` INT(10) UNSIGNED NOT NULL comment 'The phone number of the person should be the mobile one but leaves room for home ones', `phone` BIGINT(10) UNSIGNED NOT NULL comment 'The phone number of the person should be the mobile one but leaves room for home ones',
`status` ENUM('ACTIVE', 'INACTIVE') NOT NULL DEFAULT 'ACTIVE', `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', `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', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment 'The date of the last time the row was modified',

View File

@@ -6,7 +6,7 @@ services:
ports: ports:
- "8085:80" - "8085:80"
volumes: volumes:
- api-payroll:/var/www/site - ./volumes/apache-logs:/var/log/apache2
depends_on: depends_on:
- mysql - mysql
mysql: mysql:
@@ -18,11 +18,11 @@ services:
ports: ports:
- "3307:3307" - "3307:3307"
volumes: volumes:
- my-datavolume:/var/lib/mysql - ./volumes/mysql-data:/var/lib/mysql
environment: environment:
MYSQL_ROOT_PASSWORD: '12345678' MYSQL_ROOT_PASSWORD: '12345678'
MYSQL_USER: 'sloth' MYSQL_USER: 'sloth'
MYSQL_PASS: '12345678' MYSQL_PASS: '12345678'
volumes: volumes:
api-payroll: mysql-data:
my-datavolume: apache-logs:

2
volumes/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
mysql-data/
apache-logs/

1
volumes/README.md Normal file
View File

@@ -0,0 +1 @@
# Do not delete this directory, it'll contain the volumes created by the containers