style fixes and time recording app draft

This commit is contained in:
Dennis Eichhorn 2019-09-28 20:59:03 +02:00
parent 06cfffe263
commit d3c7817e28
12 changed files with 387 additions and 65 deletions

View File

@ -15,6 +15,11 @@
"null": false,
"foreignTable": "account",
"foreignKey": "account_id"
},
"hr_staff_smiPHash": {
"name": "hr_staff_smiPHash",
"type": "VARCHAR(256)",
"null": false
}
}
},

View File

@ -8,7 +8,7 @@ use phpOMS\Router\RouteVerb;
return [
'^.*/humanresource/staff.*$' => [
[
'dest' => '\Modules\HumanResourceManagement\Controller\ApiController:apiEmployeeFromAccountCreate',
'dest' => '\Modules\HumanResourceManagement\Controller\ApiController:apiEmployeeCreate',
'verb' => RouteVerb::PUT,
'permission' => [
'module' => ApiController::MODULE_NAME,

View File

@ -19,13 +19,14 @@ use Modules\HumanResourceManagement\Models\EmployeeMapper;
use Modules\HumanResourceManagement\Models\EmployeeHistory;
use Modules\HumanResourceManagement\Models\EmployeeHistoryMapper;
use phpOMS\Account\Account;
use phpOMS\Localization\ISO639x1Enum;
use phpOMS\Message\NotificationLevel;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Model\Message\FormValidation;
use phpOMS\Utils\Parser\Markdown\Markdown;
use Modules\Admin\Models\Account;
use Modules\Profile\Models\Profile;
/**
* HumanResourceManagement controller class.
@ -37,6 +38,28 @@ use phpOMS\Utils\Parser\Markdown\Markdown;
*/
final class ApiController extends Controller
{
/**
* Api method to create an employee from an existing account
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiEmployeeCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
if ($request->getData('accounts') !== null) {
$this->apiEmployeeFromAccountCreate($request, $response, $data);
}
$this->apiEmployeeNewCreate($request, $response, $data);
}
/**
* Api method to create an employee from an existing account
*
@ -58,9 +81,9 @@ final class ApiController extends Controller
return;
}
$employee = $this->createEmployeeFromAccountFromRequest($request);
$this->createModel($request->getHeader()->getAccount(), $employee, EmployeeMapper::class, 'employee');
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Employee', 'Employee successfully created', $employee);
$employees = $this->createEmployeeFromAccountFromRequest($request);
$this->createModels($request->getHeader()->getAccount(), $employees, EmployeeMapper::class, 'employee');
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Employee', 'Employee(s) successfully created', $employees);
}
/**
@ -75,8 +98,7 @@ final class ApiController extends Controller
private function validateEmployeeFromAccountCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['account'] = empty($request->getData('account')))
) {
if (($val['account'] = empty($request->getData('account')))) {
return $val;
}
@ -88,14 +110,91 @@ final class ApiController extends Controller
*
* @param RequestAbstract $request Request
*
* @return Employee[]
*
* @since 1.0.0
*/
private function createEmployeeFromAccountFromRequest(RequestAbstract $request) : array
{
$accounts = $request->getData('cc') ?? [];
if (!\is_array($accounts)) {
$accounts = [$accounts];
}
$employees = [];
foreach ($accounts as $account) {
$employees[] = new Employee((int) $account);
}
return $employees;
}
/**
* Api method to create a new employee
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiEmployeeNewCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
if (!empty($val = $this->validateEmployeeNewCreate($request))) {
$response->set('employee_create', new FormValidation($val));
return;
}
$employee = $this->createEmployeeNewFromRequest($request);
$this->createModel($request->getHeader()->getAccount(), $employee, EmployeeMapper::class, 'employee');
$this->fillJsonResponse($request, $response, NotificationLevel::OK, 'Employee', 'Employee successfully created', $employee);
}
/**
* Validate employee create request
*
* @param RequestAbstract $request Request
*
* @return array<string, bool>
*
* @since 1.0.0
*/
private function validateEmployeeNewCreate(RequestAbstract $request) : array
{
$val = [];
if (($val['name1'] = empty($request->getData('name1')))) {
return $val;
}
return [];
}
/**
* Method to create a new employee from request.
*
* @param RequestAbstract $request Request
*
* @return Employee
*
* @since 1.0.0
*/
private function createEmployeeFromAccountFromRequest(RequestAbstract $request) : Employee
private function createEmployeeNewFromRequest(RequestAbstract $request) : Employee
{
$employee = new Employee();
$employee->setAccount((int) ($request->getData('account') ?? 0));
$account = new Account();
$account->setName1((string) ($request->getData('name1') ?? ''));
$account->setName2((string) ($request->getData('name2') ?? ''));
$account->setName3((string) ($request->getData('name3') ?? ''));
$account->setName3((string) ($request->getData('email') ?? ''));
$profile = new Profile($account);
$profile->setBirthday(new \DateTime((string) ($request->getData('birthday') ?? 'now')));
$employee = new Employee($profile);
return $employee;
}

View File

@ -35,33 +35,199 @@ class Employee implements ArrayableInterface, \JsonSerializable
*/
private int $id = 0;
private $account = null;
/**
* Account profile.
*
* @var null|int|Profile
* @since 1.0.0
*/
private $profile = null;
private $history = [];
/**
* Employee department/position history.
*
* @var array
* @since 1.0.0
*/
private array $companyHistory = [];
public function setAccount($account) : void
/**
* Employee education history.
*
* @todo: implement!
*
* @var array
* @since 1.0.0
*/
private array $educationHistory = [];
/**
* Employee external work history.
*
* @var array
* @since 1.0.0
*/
private array $workHistory = [];
/**
* Employee hash used for time tracking / employee card
*
* @var string
* @since 1.0.0
*/
private string $semiPrivateHash = '';
/**
* Employee hash length used for time tracking / employee card
*
* @var int
* @since 1.0.0
*/
private const SEMI_PRIVATE_HASH_LENGTH = 64;
/**
* Constructor.
*
* @param null|Profile $profile Account profile to initialize this employee with
*
* @since 1.0.0
*/
public function __construct($profile = null)
{
$this->account = $account;
}
public function getAccount()
{
return $this->account;
$this->profile = $profile;
$this->semiPrivateHash = \random_bytes(self::SEMI_PRIVATE_HASH_LENGTH);
}
/**
* Get account id.
*
* @return int Account id
*
* @since 1.0.0
*/
public function getId() : int
{
return $this->id;
}
public function getHistory() : array
/**
* Get profile.
*
* @return null|int|Profile
*
* @since 1.0.0
*/
public function getProfile()
{
return $this->history;
return $this->profile;
}
/**
* Update semi private hash.
*
* @return void
*
* @since 1.0.0
*/
public function updateSemiPrivateHash() : void
{
$this->semiPrivateHash = \random_bytes(self::SEMI_PRIVATE_HASH_LENGTH);
}
/**
* Get semi private hash.
*
* @return string
*
* @since 1.0.0
*/
public function getSemiPrivateHash() : string
{
return $this->semiPrivateHash;
}
/**
* Compare two hashs
*
* @return bool
*
* @since 1.0.0
*/
public function compareSemiPrivateHash(string $hash) : bool
{
return \hash_equals($this->semiPrivateHash, $hash);
}
/**
* Get employee company history.
*
* @return array Employee history
*
* @since 1.0.0
*/
public function getHistory() : array
{
return $this->companyHistory;
}
/**
* Get newest company history.
*
* @return EmployeeHistory
*
* @since 1.0.0
*/
public function getNewestHistory() : EmployeeHistory
{
return empty($this->history) ? new NullEmployeeHistory : end($this->history);
return empty($this->companyHistory) ? new NullEmployeeHistory : end($this->companyHistory);
}
/**
* Get employee company education history.
*
* @return array Employee education history
*
* @since 1.0.0
*/
public function getEducationHistory() : array
{
return $this->educationHistory;
}
/**
* Get newest company education history.
*
* @return EmployeeEducationHistory
*
* @since 1.0.0
*/
public function getNewestEducationHistory() : EmployeeEducationHistory
{
return empty($this->educationHistory) ? new NullEmployeeEducationHistory : end($this->educationHistory);
}
/**
* Get employee company work.
*
* @return array Employee work
*
* @since 1.0.0
*/
public function getWorkHistory() : array
{
return $this->workHistory;
}
/**
* Get newest company work.
*
* @return EmployeeWorkHistory
*
* @since 1.0.0
*/
public function getNewestWorkHistory() : EmployeeWorkHistory
{
return empty($this->workHistory) ? new NullEmployeeWorkHistory : end($this->workHistory);
}
/**
@ -70,8 +236,8 @@ class Employee implements ArrayableInterface, \JsonSerializable
public function toArray() : array
{
return [
'id' => $this->id,
'account' => $this->account,
'id' => $this->id,
'profile' => $this->profile,
];
}

View File

@ -0,0 +1,31 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package Modules\HumanResourceManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\HumanResourceManagement\Models;
use phpOMS\Stdlib\Base\Enum;
/**
* Employee activity status enum.
*
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
abstract class EmployeeActivityStatus extends Enum
{
public const ACTIVE = 1;
public const INACTIVE = 2;
}

View File

@ -5,7 +5,7 @@
*
* PHP Version 7.4
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -23,7 +23,7 @@ use Modules\Organization\Models\UnitMapper;
/**
* EmployeHistory mapper class.
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0

View File

@ -5,7 +5,7 @@
*
* PHP Version 7.4
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -15,13 +15,13 @@ declare(strict_types=1);
namespace Modules\HumanResourceManagement\Models;
use Modules\Admin\Models\AccountMapper;
use phpOMS\DataStorage\Database\DataMapperAbstract;
use Modules\Profile\Models\ProfileMapper;
/**
* Employe mapper class.
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
@ -36,8 +36,9 @@ final class EmployeeMapper extends DataMapperAbstract
* @since 1.0.0
*/
protected static array $columns = [
'hr_staff_id' => ['name' => 'hr_staff_id', 'type' => 'int', 'internal' => 'id'],
'hr_staff_account' => ['name' => 'hr_staff_account', 'type' => 'int', 'internal' => 'account'],
'hr_staff_id' => ['name' => 'hr_staff_id', 'type' => 'int', 'internal' => 'id'],
'hr_staff_account' => ['name' => 'hr_staff_account', 'type' => 'int', 'internal' => 'account'],
'hr_staff_smiPHash' => ['name' => 'hr_staff_smiPHash', 'type' => 'int', 'internal' => 'semiPrivateHash'],
];
/**
@ -48,7 +49,7 @@ final class EmployeeMapper extends DataMapperAbstract
*/
protected static array $belongsTo = [
'account' => [
'mapper' => AccountMapper::class,
'mapper' => ProfileMapper::class,
'src' => 'hr_staff_account',
],
];
@ -60,7 +61,7 @@ final class EmployeeMapper extends DataMapperAbstract
* @since 1.0.0
*/
protected static array $hasMany = [
'history' => [
'company' => [
'mapper' => EmployeeHistoryMapper::class,
'table' => 'hr_staff_history',
'dst' => 'hr_staff_history_staff',

View File

@ -4,7 +4,7 @@
*
* PHP Version 7.4
*
* @package Modules\News
* @package Modules\News\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -17,7 +17,7 @@ namespace Modules\HumanResourceManagement\Models;
/**
* Null model
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0

View File

@ -4,7 +4,7 @@
*
* PHP Version 7.4
*
* @package Modules\News
* @package Modules\News\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -17,7 +17,7 @@ namespace Modules\HumanResourceManagement\Models;
/**
* Null model
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0

View File

@ -4,7 +4,7 @@
*
* PHP Version 7.4
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -19,7 +19,7 @@ use phpOMS\Stdlib\Base\Enum;
/**
* Permision state enum.
*
* @package Modules\HumanResourceManagement
* @package Modules\HumanResourceManagement\Models
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0

View File

@ -11,17 +11,24 @@
* @link https://orange-management.org
*/
return ['HumanResourceManagement' => [
'Account' => 'Account',
'Active' => 'Active',
'End' => 'End',
'Inactive' => 'Inactive',
'CreateFromAccount' => 'Create from account',
'Birthday' => 'Birthday',
'Clocking' => 'Clocking',
'Department' => 'Department',
'Departments' => 'Departments',
'Email' => 'Email',
'Employee' => 'Employee',
'Employees' => 'Employees',
'History' => 'History',
'Name' => 'Name',
'Parent' => 'Parent',
'Personnel' => 'Personnel',
'Position' => 'Position',
'Start' => 'Start',
'Shifts' => 'Shifts',
'Staff' => 'Staff',
'Status' => 'Status',

View File

@ -10,6 +10,9 @@
* @version 1.0.0
* @link https://orange-management.org
*/
use \Modules\HumanResourceManagement\Models\EmployeeActivityStatus;
/**
* @var \phpOMS\Views\View $this
*/
@ -18,53 +21,63 @@ echo $this->getData('nav')->render();
?>
<div class="row">
<div class="col-xs-12 col-md-4">
<div class="col-xs-12 col-md-6">
<section class="box wf-100">
<header><h1><?= $this->getHtml('Account'); ?></h1></header>
<header><h1><?= $this->getHtml('Employee'); ?></h1></header>
<div class="inner">
<form id="fAccount" action="<?= \phpOMS\Uri\UriFactory::build('{/api}admin/account'); ?>" method="put">
<form id="fEmployee" action="<?= \phpOMS\Uri\UriFactory::build('{/api}humanresource/staff'); ?>" method="put">
<table class="layout wf-100">
<tbody>
<tr><td><label for="iType"><?= $this->getHtml('Type'); ?></label>
<tr><td><select id="Type" name="type">
<option value="<?= $this->printHtml(\phpOMS\Account\AccountType::USER); ?>"><?= $this->getHtml('Person'); ?>
<option value="<?= $this->printHtml(\phpOMS\Account\AccountType::GROUP); ?>"><?= $this->getHtml('Organization'); ?>
</select>
<tr><td><label for="iStatus"><?= $this->getHtml('Status'); ?></label>
<tr><td><select id="iStatus" name="status">
<option value="<?= $this->printHtml(\phpOMS\Account\AccountStatus::ACTIVE); ?>"><?= $this->getHtml('Active'); ?>
<option value="<?= $this->printHtml(\phpOMS\Account\AccountStatus::INACTIVE); ?>"><?= $this->getHtml('Inactive'); ?>
<option value="<?= $this->printHtml(\phpOMS\Account\AccountStatus::TIMEOUT); ?>"><?= $this->getHtml('Timeout'); ?>
<option value="<?= $this->printHtml(\phpOMS\Account\AccountStatus::BANNED); ?>"><?= $this->getHtml('Banned'); ?>
<option value="<?= $this->printHtml(EmployeeActivityStatus::ACTIVE); ?>"><?= $this->getHtml('Active'); ?>
<option value="<?= $this->printHtml(EmployeeActivityStatus::INACTIVE); ?>"><?= $this->getHtml('Inactive'); ?>
</select>
<tr><td><label for="iUsername"><?= $this->getHtml('Username'); ?></label>
<tr><td><input id="iUsername" name="login" type="text" placeholder="&#xf007; Fred">
<tr><td><label for="iName1"><?= $this->getHtml('Name1'); ?></label>
<tr><td><label for="iName1"><?= $this->getHtml('Name1', 'Admin'); ?></label>
<tr><td><input id="iName1" name="name1" type="text" placeholder="&#xf007; Donald" required>
<tr><td><label for="iName2"><?= $this->getHtml('Name2'); ?></label>
<tr><td><label for="iName2"><?= $this->getHtml('Name2', 'Admin'); ?></label>
<tr><td><input id="iName2" name="name2" type="text" placeholder="&#xf007; Fauntleroy">
<tr><td><label for="iName3"><?= $this->getHtml('Name3'); ?></label>
<tr><td><label for="iName3"><?= $this->getHtml('Name3', 'Admin'); ?></label>
<tr><td><input id="iName3" name="name3" type="text" placeholder="&#xf007; Duck">
<tr><td><label for="iEmail"><?= $this->getHtml('Email'); ?></label>
<tr><td><label for="iAddress"><?= $this->getHtml('Address', 'Profile') ?></label>
<tr><td><input type="text" id="iAddress" name="address">
<tr><td><label for="iZip"><?= $this->getHtml('Zip', 'Profile') ?></label>
<tr><td><input type="text" id="iZip" name="zip">
<tr><td><label for="iCity"><?= $this->getHtml('City', 'Profile') ?></label>
<tr><td><input type="text" id="iCity" name="city">
<tr><td><label for="iCountry"><?= $this->getHtml('Country', 'Profile') ?></label>
<tr><td><input type="text" id="iCountry" name="country">
<tr><td><label for="iBirthday"><?= $this->getHtml('Birthday', 'Profile'); ?></label>
<tr><td><input id="iBirthday" name="pirthday" type="text">
<tr><td><label for="iPhone"><?= $this->getHtml('Phone', 'Profile'); ?></label>
<tr><td><input id="iPhone" name="phone" type="text">
<tr><td><label for="iEmail"><?= $this->getHtml('Email', 'Admin'); ?></label>
<tr><td><input id="iEmail" name="email" type="email" placeholder="&#xf0e0; d.duck@duckburg.com">
<tr><td><label for="iPassword"><?= $this->getHtml('Name3'); ?></label>
<tr><td><input id="iPassword" name="password" type="password" placeholder="&#xf023; Pa55ssw0rd?">
<tr><td><input id="account-create-submit" name="createSubmit" type="submit" value="<?= $this->getHtml('Create', '0', '0'); ?>">
<tr><td><label for="iUnit"><?= $this->getHtml('Unit', 'Organization'); ?></label>
<tr><td><input id="iUnit" name="unit" type="text">
<tr><td><label for="iPosition"><?= $this->getHtml('Position', 'Organization'); ?></label>
<tr><td><input id="iPosition" name="position" type="text">
<tr><td><label for="iStart"><?= $this->getHtml('Start'); ?></label>
<tr><td><input id="iStart" name="start" type="datetime-local">
<tr><td><label for="iEnd"><?= $this->getHtml('End'); ?></label>
<tr><td><input id="iEnd" name="end" type="datetime-local">
<tr><td><input id="employee-create-submit" name="createSubmit" type="submit" value="<?= $this->getHtml('Create', '0', '0'); ?>">
</table>
</form>
</div>
</section>
</div>
<div class="col-xs-12 col-md-4">
<div class="col-xs-12 col-md-6">
<section class="box wf-100">
<header><h1><?= $this->getHtml('CreateFromExistingAccount'); ?></h1></header>
<header><h1><?= $this->getHtml('CreateFromAccount'); ?></h1></header>
<div class="inner">
<form id="fAccount" action="<?= \phpOMS\Uri\UriFactory::build('{/api}admin/account'); ?>" method="put">
<form id="fAccount" action="<?= \phpOMS\Uri\UriFactory::build('{/api}humanresource/staff'); ?>" method="put">
<table class="layout wf-100">
<tbody>
<tr><td><label for="iAccount"><?= $this->getHtml('Account'); ?></label>
<tr><td><?= $this->getData('accSelector')->render('iAccount', 'account', true); ?>
<tr><td><label for="iAccount"><?= $this->getHtml('Account', 'Admin'); ?></label>
<tr><td><?= $this->getData('accSelector')->render('iAccount', 'accounts', true); ?>
<tr><td><input id="employee-create-submit" name="createSubmit" type="submit" value="<?= $this->getHtml('Create', '0', '0'); ?>">
</table>
</form>
</div>