This commit is contained in:
Dennis Eichhorn 2024-01-02 23:34:17 +00:00
parent 77d329f40d
commit a6a0c80d88
15 changed files with 64 additions and 41 deletions

View File

@ -94,27 +94,29 @@ final class ApiController extends Controller
->limit(1) ->limit(1)
->execute(); ->execute();
if ($employee->id === 0) {
return null;
}
$type = $request->getDataInt('type') ?? ClockingType::OFFICE; $type = $request->getDataInt('type') ?? ClockingType::OFFICE;
$status = $request->getDataInt('status') ?? ClockingStatus::START; $status = $request->getDataInt('status') ?? ClockingStatus::START;
if ($employee->id === 0) { if (!ClockingStatus::isValidValue($status)) {
return null; return null;
} }
$session = new Session($employee); $session = new Session($employee);
$session->setType(ClockingType::isValidValue($type) ? $type : ClockingType::OFFICE); $session->setType(ClockingType::isValidValue($type) ? $type : ClockingType::OFFICE);
if (ClockingStatus::isValidValue($status)) { // a custom datetime can only be set if the user is allowed to create a session for a foreign account or if the session is a vacation
// a custom datetime can only be set if the user is allowed to create a session for a foreign account or if the session is a vacation $dt = $request->hasData('account') || $type === ClockingType::VACATION
$dt = $request->hasData('account') || $type === ClockingType::VACATION ? ($request->getDataDateTime('datetime') ?? new \DateTime('now'))
? ($request->getDataDateTime('datetime') ?? new \DateTime('now')) : new \DateTime('now');
: new \DateTime('now');
$element = new SessionElement($session, $dt); $element = new SessionElement($session, $dt);
$element->setStatus($status); $element->setStatus($status);
$session->addSessionElement($element); $session->addSessionElement($element);
}
return $session; return $session;
} }
@ -147,7 +149,9 @@ final class ApiController extends Controller
return; return;
} }
if ($request->hasData('account') && ((int) $request->getData('account')) !== $request->header->account && !$this->app->accountManager->get($request->header->account)->hasPermission( if ($request->hasData('account')
&& $request->getDataInt('account') !== $request->header->account
&& !$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::CREATE, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::SESSION_ELEMENT_FOREIGN PermissionType::CREATE, $this->app->unitId, $this->app->appId, self::NAME, PermissionCategory::SESSION_ELEMENT_FOREIGN
)) { )) {
$response->header->status = RequestStatusCode::R_403; $response->header->status = RequestStatusCode::R_403;
@ -205,8 +209,6 @@ final class ApiController extends Controller
*/ */
private function createSessionElementFromRequest(RequestAbstract $request) : ?SessionElement private function createSessionElementFromRequest(RequestAbstract $request) : ?SessionElement
{ {
$account = $request->getDataInt('account') ?? $request->header->account;
/** @var Session $session */ /** @var Session $session */
$session = SessionMapper::get()->where('id', (int) $request->getData('session'))->execute(); $session = SessionMapper::get()->where('id', (int) $request->getData('session'))->execute();

View File

@ -46,14 +46,25 @@ final class BackendController extends Controller implements DashboardElementInte
$view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1006301001, $request, $response); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1006301001, $request, $response);
/** @var \Modules\HumanResourceTimeRecording\Models\Session[] $list */ /** @var \Modules\HumanResourceTimeRecording\Models\Session[] $list */
$list = SessionMapper::getLastSessionsFromAllEmployees(); $list = SessionMapper::getLastSessionsFromAllEmployees();
$view->data['sessions'] = $list;
$sessions = [];
foreach ($list as $session) {
$sessions[$session->employee->id] = $session;
}
$view->data['sessions'] = $sessions;
$view->data['employees'] = EmployeeMapper::getAll()
->with('profile')
->with('profile/account')
->execute();
return $view; return $view;
} }
/** /**
* Routing end-point for application behaviour. * Routing end-point for application behavior.
* *
* @param RequestAbstract $request Request * @param RequestAbstract $request Request
* @param ResponseAbstract $response Response * @param ResponseAbstract $response Response
@ -99,7 +110,7 @@ final class BackendController extends Controller implements DashboardElementInte
} }
/** /**
* Routing end-point for application behaviour. * Routing end-point for application behavior.
* *
* @param RequestAbstract $request Request * @param RequestAbstract $request Request
* @param ResponseAbstract $response Response * @param ResponseAbstract $response Response
@ -136,7 +147,7 @@ final class BackendController extends Controller implements DashboardElementInte
} }
/** /**
* Routing end-point for application behaviour. * Routing end-point for application behavior.
* *
* @param RequestAbstract $request Request * @param RequestAbstract $request Request
* @param ResponseAbstract $response Response * @param ResponseAbstract $response Response

View File

@ -32,7 +32,7 @@ use phpOMS\Views\View;
final class TimerecordingController extends Controller final class TimerecordingController extends Controller
{ {
/** /**
* Routing end-point for application behaviour. * Routing end-point for application behavior.
* *
* @param RequestAbstract $request Request * @param RequestAbstract $request Request
* @param ResponseAbstract $response Response * @param ResponseAbstract $response Response

View File

@ -37,4 +37,6 @@ abstract class ClockingType extends Enum
public const SICK = 5; public const SICK = 5;
public const ON_THE_MOVE = 6; public const ON_THE_MOVE = 6;
public const NO_DATA = -1;
} }

View File

@ -17,7 +17,7 @@ namespace Modules\HumanResourceTimeRecording\Models;
use phpOMS\Stdlib\Base\Enum; use phpOMS\Stdlib\Base\Enum;
/** /**
* Permision state enum. * Permission category enum.
* *
* @package Modules\HumanResourceTimeRecording\Models * @package Modules\HumanResourceTimeRecording\Models
* @license OMS License 2.0 * @license OMS License 2.0

View File

@ -65,7 +65,7 @@ class Session implements \JsonSerializable
* @var int * @var int
* @since 1.0.0 * @since 1.0.0
*/ */
public int $type = ClockingType::OFFICE; public int $type = ClockingType::NO_DATA;
/** /**
* Session elements. * Session elements.

View File

@ -115,11 +115,12 @@ final class SessionMapper extends DataMapperFactory
->groupBy(self::TABLE . '.hr_timerecording_session_employee'); ->groupBy(self::TABLE . '.hr_timerecording_session_employee');
$query = self::getQuery(); $query = self::getQuery();
$query->innerJoin($join, 'tm') $query->leftJoin($join, 'tm')
->on(self::TABLE . '_d1.hr_timerecording_session_employee', '=', 'tm.hr_timerecording_session_employee') ->on(self::TABLE . '_d1.hr_timerecording_session_employee', '=', 'tm.hr_timerecording_session_employee')
->andOn(self::TABLE . '_d1.hr_timerecording_session_start', '=', 'tm.maxDate'); ->andOn(self::TABLE . '_d1.hr_timerecording_session_start', '=', 'tm.maxDate');
return self::getAll()->execute($query); return self::getAll()
->execute($query);
} }
/** /**

View File

@ -24,6 +24,7 @@ return ['HumanResourceTimeRecording' => [
'CT4' => 'Urlaub', 'CT4' => 'Urlaub',
'CT5' => 'Krank', 'CT5' => 'Krank',
'CT6' => 'Unterwegs', 'CT6' => 'Unterwegs',
'CT-1' => 'Keine Daten',
'D0' => 'Sonntag', 'D0' => 'Sonntag',
'D1' => 'Montag', 'D1' => 'Montag',
'D2' => 'Dienstag', 'D2' => 'Dienstag',

View File

@ -24,6 +24,7 @@ return ['HumanResourceTimeRecording' => [
'CT4' => 'Vacation', 'CT4' => 'Vacation',
'CT5' => 'Sick', 'CT5' => 'Sick',
'CT6' => 'On the move', 'CT6' => 'On the move',
'CT-1' => 'No data',
'D0' => 'Sunday', 'D0' => 'Sunday',
'D1' => 'Monday', 'D1' => 'Monday',
'D2' => 'Tuesday', 'D2' => 'Tuesday',

View File

@ -12,36 +12,41 @@
*/ */
declare(strict_types=1); declare(strict_types=1);
$sessions = $this->data['sessions']; use Modules\HumanResourceTimeRecording\Models\ClockingType;
$date = new \DateTime('now');
echo $this->data['nav']->render(); ?> echo $this->data['nav']->render(); ?>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box wf-100"> <div class="portlet">
<table id="accountList" class="default"> <div class="portlet-head"><?= $this->getHtml('Status'); ?><i class="g-icon download btn end-xs">download</i></div>
<caption><?= $this->getHtml('Recordings'); ?><i class="g-icon end-xs download btn">download</i></caption> <div class="slider">
<table id="employeeList" class="default sticky">
<thead> <thead>
<tr> <tr>
<td><?= $this->getHtml('Date'); ?> <td><?= $this->getHtml('Date'); ?>
<td><?= $this->getHtml('Type'); ?> <td><?= $this->getHtml('Type'); ?>
<td><?= $this->getHtml('Employee'); ?> <td class="wf-100"><?= $this->getHtml('Employee'); ?>
<td><?= $this->getHtml('Start'); ?> <td><?= $this->getHtml('Start'); ?>
<td><?= $this->getHtml('Break'); ?> <td><?= $this->getHtml('Break'); ?>
<td><?= $this->getHtml('End'); ?> <td><?= $this->getHtml('End'); ?>
<td><?= $this->getHtml('Total'); ?> <td><?= $this->getHtml('Total'); ?>
<tbody> <tbody>
<?php foreach ($sessions as $session) : ?> <?php foreach ($this->data['employees'] as $employee) :
$session = $this->data['sessions'][$employee->id] ?? null;
?>
<tr> <tr>
<td><?= $session->getStart()->format('Y-m-d'); ?> <td><?= $session?->getStart()->format('Y-m-d') ?? $date->format('Y-m-d H:i:s'); ?>
<td><span class="tag"><?= $this->getHtml('CT' . $session->getType()); ?></span> <td><span class="tag"><?= $this->getHtml('CT' . ($session?->type ?? ClockingType::NO_DATA)); ?></span>
<td> <td>
<?= $this->printHtml($session->getEmployee()->profile->account->name1); ?>, <?= $this->printHtml($employee->profile->account->name1); ?>,
<?= $this->printHtml($session->getEmployee()->profile->account->name2); ?> <?= $this->printHtml($employee->profile->account->name2); ?>
<td><?= $session->getStart()->format('H:i:s'); ?> <td><?= $session?->getStart()->format('H:i:s'); ?>
<td><?= (int) ($session->getBreak() / 3600); ?>h <?= ((int) ($session->getBreak() / 60) % 60); ?>m <td><?= $session !== null ? ((int) ($session->getBreak() / 3600)) . 'h' : ''; ?> <?= $session !== null ? ((int) ($session->getBreak() / 60) % 60) . 'm' : ''; ?>
<td><?= $session->getEnd() !== null ? $session->getEnd()->format('H:i') : ''; ?> <td><?= $session?->getEnd() !== null ? $session->getEnd()->format('H:i') : ''; ?>
<td><?= (int) ($session->getBusy() / 3600); ?>h <?= ((int) ($session->getBusy() / 60) % 60); ?>m <td><?= $session !== null ? ((int) ($session->getBusy() / 3600)) . 'h' : ''; ?> <?= $session !== null ? ((int) ($session->getBusy() / 60) % 60) . 'm' : ''; ?>
<?php endforeach; ?> <?php endforeach; ?>
</table> </table>
</div> </div>

View File

@ -113,7 +113,7 @@ echo $this->data['nav']->render(); ?>
<div class="col-xs-12"> <div class="col-xs-12">
<section class="portlet"> <section class="portlet">
<div class="portlet-head"><?= $this->getHtml('Recordings'); ?><i class="g-icon download btn end-xs">download</i></div> <div class="portlet-head"><?= $this->getHtml('Recordings'); ?><i class="g-icon download btn end-xs">download</i></div>
<table id="recordingList" class="default"> <table id="recordingList" class="default sticky">
<thead> <thead>
<tr> <tr>
<td><?= $this->getHtml('Date'); ?> <td><?= $this->getHtml('Date'); ?>

View File

@ -21,7 +21,7 @@ echo $this->data['nav']->render(); ?>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box wf-100"> <div class="box wf-100">
<table id="accountList" class="default"> <table id="sessionList" class="default sticky">
<caption><?= $session->start->format('Y-m-d'); ?><i class="g-icon end-xs download btn">download</i></caption> <caption><?= $session->start->format('Y-m-d'); ?><i class="g-icon end-xs download btn">download</i></caption>
<thead> <thead>
<tr> <tr>

View File

@ -81,7 +81,7 @@ echo $this->data['nav']->render(); ?>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box wf-100"> <div class="box wf-100">
<table id="accountList" class="default"> <table id="accountList" class="default sticky">
<caption><?= $this->getHtml('Recordings'); ?><i class="g-icon end-xs download btn">download</i></caption> <caption><?= $this->getHtml('Recordings'); ?><i class="g-icon end-xs download btn">download</i></caption>
<thead> <thead>
<tr> <tr>

View File

@ -14,7 +14,6 @@
"name": "Jingga", "name": "Jingga",
"website": "jingga.app" "website": "jingga.app"
}, },
"description": "The administration module.",
"directory": "HumanResourceTimeRecording", "directory": "HumanResourceTimeRecording",
"dependencies": { "dependencies": {
"Admin": "1.0.0", "Admin": "1.0.0",

View File

@ -61,6 +61,7 @@ final class ApiControllerTest extends \PHPUnit\Framework\TestCase
$this->app = new class() extends ApplicationAbstract $this->app = new class() extends ApplicationAbstract
{ {
protected string $appName = 'Api'; protected string $appName = 'Api';
protected int $appId = 1; protected int $appId = 1;
}; };