This commit is contained in:
Dennis Eichhorn 2024-04-07 17:31:42 +00:00
parent 4e81fb41cf
commit a8d5939460
14 changed files with 62 additions and 63 deletions

View File

@ -5,6 +5,7 @@ return [
0 => [
'dest' => '\Modules\HumanResourceTimeRecording\Controller\TimerecordingController:viewDashboard',
'verb' => 1,
'active' => true,
'permission' => [
'module' => 'HumanResourceTimeRecording',
'type' => 2,
@ -16,6 +17,7 @@ return [
0 => [
'dest' => '\Modules\HumanResourceTimeRecording\Controller\TimerecordingController:viewDashboard',
'verb' => 1,
'active' => true,
'permission' => [
'module' => 'HumanResourceTimeRecording',
'type' => 2,

View File

@ -18,7 +18,7 @@
"pid": "/humanresource/timerecording",
"type": 3,
"subtype": 1,
"name": "Today",
"name": "Dashboard",
"uri": "{/base}/humanresource/timerecording/dashboard?{?}",
"target": "self",
"icon": null,

View File

@ -23,6 +23,7 @@ return [
'dest' => '\Modules\HumanResourceTimeRecording\Controller\ApiController:apiSessionCreate',
'verb' => RouteVerb::PUT,
'csrf' => true,
'active' => true,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::CREATE,
@ -35,6 +36,7 @@ return [
'dest' => '\Modules\HumanResourceTimeRecording\Controller\ApiController:apiSessionElementCreate',
'verb' => RouteVerb::PUT,
'csrf' => true,
'active' => true,
'permission' => [
'module' => ApiController::NAME,
'type' => PermissionType::CREATE,

View File

@ -22,6 +22,7 @@ return [
[
'dest' => '\Modules\HumanResourceTimeRecording\Controller\BackendController:viewDashboard',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -33,6 +34,7 @@ return [
[
'dest' => '\Modules\HumanResourceTimeRecording\Controller\BackendController:viewPrivateDashboard',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,
@ -44,6 +46,7 @@ return [
[
'dest' => '\Modules\HumanResourceTimeRecording\Controller\BackendController:viewPrivateSession',
'verb' => RouteVerb::GET,
'active' => true,
'permission' => [
'module' => BackendController::NAME,
'type' => PermissionType::READ,

View File

@ -91,7 +91,8 @@ final class ApiController extends Controller
$element = new SessionElement($session, $dt);
$element->status = ClockingStatus::tryFromValue($request->getDataInt('status')) ?? ClockingStatus::START;
$session->addSessionElement($element);
$session->sessionElements[] = $element;
$session->recalculate();
return $session;
}
@ -111,7 +112,9 @@ final class ApiController extends Controller
*/
public function apiSessionElementCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void
{
if (($request->getDataInt('status') ?? -1) === ClockingStatus::START) {
if (!$request->hasData('session') &&
($request->getDataInt('status') ?? -1) === ClockingStatus::START
) {
$this->apiSessionCreate($request, $response);
return;
@ -146,9 +149,12 @@ final class ApiController extends Controller
if ($element->status === ClockingStatus::END) {
/** @var \Modules\HumanResourceTimeRecording\Models\Session $session */
$session = SessionMapper::get()->where('id', (int) $request->getData('session'))->execute();
$session = SessionMapper::get()
->with('sessionElements')
->where('id', (int) $request->getData('session'))
->execute();
$session->addSessionElement($element);
$session->recalculate();
SessionMapper::update()->execute($session);
}

View File

@ -105,56 +105,35 @@ class Session implements \JsonSerializable
$this->createdAt = new \DateTimeImmutable('now');
}
/**
* Get busy time.
*
* @return int
*
* @since 1.0.0
*/
public function getBusy() : int
public function recalculate() : void
{
return $this->busy;
}
/**
* Add a session element to the session
*
* @param SessionElement $element Session element
*
* @return void
*
* @since 1.0.0
*/
public function addSessionElement(SessionElement $element) : void
{
if ($element->status === ClockingStatus::START) {
foreach ($this->sessionElements as $e) {
if ($e->status === ClockingStatus::START) {
return;
}
}
$this->start = $element->datetime;
}
if ($element->status === ClockingStatus::END) {
if ($this->end !== null) {
return;
}
$this->end = $element->datetime;
}
$this->sessionElements[] = $element;
\usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']);
$start = null;
$end = null;
foreach ($this->sessionElements as $e) {
if ($e->status === ClockingStatus::START
&& ($start === null || $start->getTimestamp() > $e->datetime->getTimestamp())
) {
$start = $e->datetime;
} elseif ($e->status === ClockingStatus::END
&& ($end === null || $end->getTimestamp() < $e->datetime->getTimestamp())
) {
$end = $e->datetime;
}
}
$this->start = $start;
$this->end = $end;
$busyTime = 0;
$lastStart = $this->start;
foreach ($this->sessionElements as $e) {
if ($e->status === ClockingStatus::START) {
$lastStart = $e->datetime;
continue;
}

View File

@ -17,7 +17,7 @@ namespace Modules\HumanResourceTimeRecording\Models;
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
/**
* Mapper class.
* SessionElement mapper class.
*
* @package Modules\HumanResourceTimeRecording\Models
* @license OMS License 2.0

View File

@ -20,7 +20,7 @@ use phpOMS\DataStorage\Database\Query\Builder;
use phpOMS\Stdlib\Base\SmartDateTime;
/**
* Mapper class.
* Session mapper class.
*
* @package Modules\HumanResourceTimeRecording\Models
* @license OMS License 2.0
@ -105,6 +105,8 @@ final class SessionMapper extends DataMapperFactory
*
* @return Session[]
*
* @performance This is way too slow
*
* @since 1.0.0
*/
public static function getLastSessionsFromAllEmployees() : array
@ -121,7 +123,7 @@ final class SessionMapper extends DataMapperFactory
->andOn(self::TABLE . '_d1.hr_timerecording_session_start', '=', 'tm.maxDate');
return self::getAll()
->execute($query);
->executeGetArray($query);
}
/**

View File

@ -17,5 +17,5 @@ return ['Navigation' => [
'List' => 'Liste',
'Stats' => 'Statistiken',
'TimeRecording' => 'Zeitaufnahme',
'Today' => 'Heute',
'Dashboard' => 'Dashboard',
]];

View File

@ -17,5 +17,5 @@ return ['Navigation' => [
'List' => 'List',
'Stats' => 'Stats',
'TimeRecording' => 'Time Recording',
'Today' => 'Today',
'Dashboard' => 'Dashboard',
]];

View File

@ -13,6 +13,7 @@
declare(strict_types=1);
use Modules\HumanResourceTimeRecording\Models\ClockingType;
use phpOMS\Uri\UriFactory;
$date = new \DateTime('now');
@ -36,17 +37,21 @@ echo $this->data['nav']->render(); ?>
<tbody>
<?php foreach ($this->data['employees'] as $employee) :
$session = $this->data['sessions'][$employee->id] ?? null;
// @todo Implement clocking view per employee for HR (also to edit clocking)
$employeeUrl = UriFactory::build('{/base}/humanresource/staff/view?id=' . $employee->id);
?>
<tr>
<td><?= $session?->getStart()->format('Y-m-d') ?? $date->format('Y-m-d H:i:s'); ?>
<td><?= $session?->start->format('Y-m-d H:i:s') ?? $date->format('Y-m-d H:i:s'); ?>
<td><span class="tag"><?= $this->getHtml('CT' . ($session?->type ?? ClockingType::NO_DATA)); ?></span>
<td>
<td><a class="content" href="<?= $employeeUrl; ?>">
<?= $this->printHtml($employee->profile->account->name1); ?>,
<?= $this->printHtml($employee->profile->account->name2); ?>
<td><?= $session?->getStart()->format('H:i:s'); ?>
</a>
<td><?= $session?->start->format('H:i:s'); ?>
<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 !== null ? ((int) ($session->getBusy() / 3600)) . 'h' : ''; ?> <?= $session !== null ? ((int) ($session->getBusy() / 60) % 60) . 'm' : ''; ?>
<td><?= $session?->end?->format('H:i') ?? ''; ?>
<td><?= $session !== null ? ((int) ($session->busy / 3600)) . 'h' : ''; ?> <?= $session !== null ? ((int) ($session->busy / 60) % 60) . 'm' : ''; ?>
<?php endforeach; ?>
</table>
</div>

View File

@ -222,9 +222,9 @@ echo $this->data['nav']->render(); ?>
<td><a href="<?= $url; ?>"><?= $session->start->format('H:i'); ?></a>
<td><a href="<?= $url; ?>"><?= (int) ($session->getBreak() / 3600); ?>h <?= ((int) ($session->getBreak() / 60) % 60); ?>m</a>
<td><a href="<?= $url; ?>"><?= $session->end?->format('H:i'); ?></a>
<td><a href="<?= $url; ?>"><?= (int) ($session->getBusy() / 3600); ?>h <?= ((int) ($session->getBusy() / 60) % 60); ?>m</a>
<td><a href="<?= $url; ?>"><?= (int) ($session->busy / 3600); ?>h <?= ((int) ($session->busy / 60) % 60); ?>m</a>
<?php
$busy['week'] += $session->getBusy();
$busy['week'] += $session->busy;
if ($session->start->getTimestamp() < $startWeek->getTimestamp()
|| $count === $sessionCount
) : ?>
@ -238,7 +238,7 @@ echo $this->data['nav']->render(); ?>
endif;
?>
<?php
$busy['month'] += $session->getBusy();
$busy['month'] += $session->busy;
if ($session->start->getTimestamp() < $startMonth->getTimestamp()
|| $count === $sessionCount
) : ?>

View File

@ -99,7 +99,7 @@ echo $this->data['nav']->render(); ?>
<td><?= $session->getStart()->format('H:i'); ?>
<td><?= (int) ($session->getBreak() / 3600); ?>h <?= ((int) ($session->getBreak() / 60) % 60); ?>m
<td><?= $session->getEnd() !== null ? $session->getEnd()->format('H:i') : ''; ?>
<td><?= (int) ($session->getBusy() / 3600); ?>h <?= ((int) ($session->getBusy() / 60) % 60); ?>m
<td><?= (int) ($session->busy / 3600); ?>h <?= ((int) ($session->busy / 60) % 60); ?>m
<?php endforeach; ?>
</table>
</div>

View File

@ -39,7 +39,7 @@ final class SessionTest extends \PHPUnit\Framework\TestCase
public function testDefault() : void
{
self::assertEquals(0, $this->session->id);
self::assertEquals(0, $this->session->getBusy());
self::assertEquals(0, $this->session->busy);
self::assertEquals(0, $this->session->getBreak());
self::assertEquals([], $this->session->getSessionElements());
self::assertEquals(ClockingType::OFFICE, $this->session->type);
@ -104,7 +104,7 @@ final class SessionTest extends \PHPUnit\Framework\TestCase
$this->session->addSessionElement($element);
self::assertEquals(2 * 60 * 60, $this->session->getBreak());
self::assertEquals(7 * 60 * 60, $this->session->getBusy());
self::assertEquals(7 * 60 * 60, $this->session->busy);
}
#[\PHPUnit\Framework\Attributes\Group('module')]