Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Exception\SupervisorNotFoundException;
|
||||
|
||||
final class GroupGateway
|
||||
{
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findGroupsByAddressId(int $addressId): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT DISTINCT
|
||||
g.id AS `group_id`,
|
||||
g.name AS `group_name`
|
||||
FROM `gruppen` AS `g`
|
||||
INNER JOIN `adresse_rolle` AS `ar` ON ar.parameter = g.id AND ar.subjekt = \'Mitglied\'
|
||||
WHERE ar.adresse = :address_id
|
||||
AND (ar.bis = \'0000-00-00\' OR ar.bis > CURDATE())';
|
||||
|
||||
return $this->db->fetchAll($sql, ['address_id' => $addressId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
* @param int $groupId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAddressInGroup(int $addressId, int $groupId): bool
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
g.id AS `group_id`,
|
||||
g.name AS `group_name`
|
||||
FROM `gruppen` AS `g`
|
||||
INNER JOIN `adresse_rolle` AS `ar` ON ar.parameter = g.id AND ar.subjekt = \'Mitglied\'
|
||||
WHERE ar.adresse = :address_id
|
||||
AND ar.parameter = :group_id
|
||||
AND (ar.bis = \'0000-00-00\' OR ar.bis > CURDATE())';
|
||||
|
||||
$result = $this->db->fetchAll($sql, ['address_id' => $addressId, 'group_id' => $groupId]);
|
||||
|
||||
return !empty($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function findAllActiveGroupsWithMembers(): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT DISTINCT
|
||||
g.id AS `group_id`,
|
||||
g.name AS `group_name`
|
||||
FROM `gruppen` AS `g`
|
||||
INNER JOIN `adresse_rolle` AS `ar` ON ar.parameter = g.id AND ar.subjekt = \'Mitglied\'
|
||||
WHERE (ar.bis = \'0000-00-00\' OR ar.bis > CURDATE())';
|
||||
|
||||
return $this->db->fetchAll($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $employeeAddressId
|
||||
* @param int $groupId
|
||||
*
|
||||
* @throws SupervisorNotFoundException
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getSupervisorAddressIds(int $employeeAddressId, int $groupId = 0): array
|
||||
{
|
||||
$bindValues = [];
|
||||
$sql =
|
||||
'SELECT a.id AS `id`
|
||||
FROM `userrights` AS `ur`
|
||||
INNER JOIN `user` AS `u` ON u.id = ur.user
|
||||
INNER JOIN `adresse` AS `a` ON a.id = u.adresse
|
||||
INNER JOIN `adresse_rolle` AS `ar_supervisor` ON ar_supervisor.adresse = a.id
|
||||
WHERE ur.action = \'timemanagementhandle\'
|
||||
AND ar_supervisor.subjekt = \'Mitglied\'
|
||||
AND ar_supervisor.objekt = \'Gruppe\'
|
||||
';
|
||||
|
||||
if ($groupId == 0) {
|
||||
$sql .= 'AND ar_supervisor.parameter IN (
|
||||
SELECT ar_employee.parameter
|
||||
FROM `adresse_rolle` AS `ar_employee`
|
||||
WHERE ar_employee.adresse = :employee_address_id
|
||||
AND ar_employee.subjekt = \'Mitglied\'
|
||||
AND ar_employee.objekt = \'Gruppe\'
|
||||
)';
|
||||
$bindValues['employee_address_id'] = $employeeAddressId;
|
||||
} else {
|
||||
$sql .= 'AND ar_supervisor.parameter = :group_id';
|
||||
$bindValues['group_id'] = $groupId;
|
||||
}
|
||||
|
||||
$superVisorAddressIds = $this->db->fetchAll($sql, $bindValues);
|
||||
|
||||
//superprivilege
|
||||
if (empty($superVisorAddressIds)) {
|
||||
$superVisorAddressIds = $this->findSupervisorAddressIdsBySuperPrivilege();
|
||||
}
|
||||
|
||||
//admin
|
||||
if (empty($superVisorAddressIds)) {
|
||||
$superVisorAddressIds = $this->findSupervisorAddressIdByAdminRight();
|
||||
}
|
||||
|
||||
$return = [];
|
||||
if (!empty($superVisorAddressIds)) {
|
||||
foreach ($superVisorAddressIds as $superVisorAddressId) {
|
||||
$return[] = $superVisorAddressId['id'];
|
||||
}
|
||||
} else {
|
||||
throw new SupervisorNotFoundException('No supervisor found for ' . $employeeAddressId);
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function findSupervisorAddressIdsBySuperPrivilege()
|
||||
{
|
||||
$sql =
|
||||
'SELECT a.id AS `id`
|
||||
FROM `userrights` AS `ur`
|
||||
INNER JOIN `user` AS `u` ON u.id = ur.user
|
||||
INNER JOIN `adresse` AS `a` ON a.id = u.adresse
|
||||
WHERE ur.action = \'timemanagementsuperprivilege\'
|
||||
ORDER BY a.id DESC';
|
||||
|
||||
return $this->db->fetchAll($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function findSupervisorAddressIdByAdminRight()
|
||||
{
|
||||
$sql =
|
||||
'SELECT u.adresse AS `id`
|
||||
FROM `user` AS `u`
|
||||
WHERE u.type = \'admin\'
|
||||
ORDER BY u.adresse DESC';
|
||||
|
||||
return $this->db->fetchAll($sql);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Data\HolidayData;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidDateFormatException;
|
||||
|
||||
final class HolidayGateway
|
||||
{
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $year
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return array|HolidayData[]
|
||||
*/
|
||||
public function findHolidayDataByYear(int $year): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
af.bezeichnung as `name`,
|
||||
af.datum as `date`
|
||||
FROM `arbeitsfreietage` AS `af`
|
||||
WHERE af.datum >= :first_date_of_year
|
||||
AND af.typ = \'feiertag\'
|
||||
ORDER BY af.datum';
|
||||
|
||||
$holidays = $this->db->fetchAll($sql, ['first_date_of_year' => $year . '-01-01']);
|
||||
|
||||
$holidayData = [];
|
||||
if (!empty($holidays)) {
|
||||
foreach ($holidays as $holiday) {
|
||||
$holidayData[] = HolidayData::fromDbState($holiday);
|
||||
}
|
||||
}
|
||||
|
||||
return $holidayData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidArgumentException;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidQueryException;
|
||||
|
||||
final class TimeManagementHistoryService
|
||||
{
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $employeeAddressId
|
||||
* @param int $supervisorAddressId
|
||||
* @param string $oldType
|
||||
* @param string $newType
|
||||
* @param string $requestToken
|
||||
* @param DateTimeInterface $from
|
||||
* @param DateTimeInterface $till
|
||||
* @param string $comment
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws InvalidQueryException
|
||||
*/
|
||||
public function saveActivity(
|
||||
int $employeeAddressId,
|
||||
int $supervisorAddressId,
|
||||
string $oldType,
|
||||
string $newType,
|
||||
string $requestToken,
|
||||
DateTimeInterface $from,
|
||||
DateTimeInterface $till,
|
||||
string $comment
|
||||
): void {
|
||||
if ($employeeAddressId === 0 && $supervisorAddressId === 0) {
|
||||
throw new InvalidArgumentException('No addresses given.');
|
||||
}
|
||||
|
||||
if (empty($oldType) && empty($newType)) {
|
||||
throw new InvalidArgumentException('No types given.');
|
||||
}
|
||||
|
||||
$sql =
|
||||
'INSERT INTO `timemanagement_history` (
|
||||
`employee_address_id`,
|
||||
`supervisor_address_id`,
|
||||
`old_day_type`,
|
||||
`new_day_type`,
|
||||
`request_token`,
|
||||
`from`,
|
||||
`till`,
|
||||
`comment`
|
||||
) VALUES (
|
||||
:employee_address_id,
|
||||
:supervisor_address_id,
|
||||
:old_day_type,
|
||||
:new_day_type,
|
||||
:request_token,
|
||||
:from,
|
||||
:till,
|
||||
:comment
|
||||
)';
|
||||
|
||||
$arguments = [
|
||||
'employee_address_id' => $employeeAddressId,
|
||||
'supervisor_address_id' => $supervisorAddressId,
|
||||
'old_day_type' => $oldType,
|
||||
'new_day_type' => $newType,
|
||||
'request_token' => $requestToken,
|
||||
'from' => $from->format('Y-m-d'),
|
||||
'till' => $till->format('Y-m-d'),
|
||||
'comment' => $comment,
|
||||
];
|
||||
|
||||
$numAffected = (int)$this->db->fetchAffected($sql, $arguments);
|
||||
|
||||
if ($numAffected === 0) {
|
||||
throw new InvalidQueryException(
|
||||
'Time management history could not be updated. Arguments: ' . implode(', ', $arguments)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Data\WorkDayData;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidQueryException;
|
||||
|
||||
final class TimeManagementSettingGateway
|
||||
{
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
*
|
||||
* @throws InvalidQueryException
|
||||
*
|
||||
* @return WorkDayData
|
||||
*/
|
||||
public function getWorkingDaysForAddress(int $addressId): WorkDayData
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
e.vorlagemo > 0 AS `is_monday_workday`,
|
||||
e.vorlagedi > 0 AS `is_tuesday_workday`,
|
||||
e.vorlagemi > 0 AS `is_wednesday_workday`,
|
||||
e.vorlagedo > 0 AS `is_thursday_workday`,
|
||||
e.vorlagefr > 0 AS `is_friday_workday`,
|
||||
e.vorlagesa > 0 AS `is_saturday_workday`,
|
||||
e.vorlageso > 0 AS `is_sunday_workday`
|
||||
FROM `mitarbeiterzeiterfassung_einstellungen` AS `e`
|
||||
WHERE e.adresse = :address_id
|
||||
ORDER BY e.id DESC
|
||||
LIMIT 1';
|
||||
|
||||
$result = $this->db->fetchRow($sql, ['address_id' => $addressId]);
|
||||
if (empty($result)) {
|
||||
throw new InvalidQueryException('Address is not valid: ' . $addressId);
|
||||
}
|
||||
|
||||
return WorkDayData::fromDbState($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use DateTimeInterface;
|
||||
use Exception;
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Data\CalendarData;
|
||||
use Xentral\Modules\TimeManagement\Data\DayInfoData;
|
||||
use Xentral\Modules\TimeManagement\Data\RequestInfoData;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidDateFormatException;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidRequestTokenException;
|
||||
|
||||
final class TimeManagementTargetHourGateway
|
||||
{
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
* @param int $addressId
|
||||
* @param int $groupId
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return array|CalendarData[]
|
||||
*/
|
||||
public function findAnonymisedVacationCalendarDataByYearAndAddressIdAndGroupId(
|
||||
int $year,
|
||||
int $addressId,
|
||||
int $groupId
|
||||
): array {
|
||||
$sql =
|
||||
'SELECT
|
||||
MONTH(days.date) AS `month`,
|
||||
days.date,
|
||||
days.address_id,
|
||||
days.name,
|
||||
days.type,
|
||||
IF(days.urlaubminuten > 0,true,false) AS `is_half`
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.adresse AS `address_id`,
|
||||
a.name,
|
||||
\'away\' AS `type`,
|
||||
ms.urlaubminuten
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON ms.adresse = a.id
|
||||
WHERE (ms.kuerzel LIKE \'%U%\' OR ms.kuerzel LIKE \'%S%\')
|
||||
AND ms.adresse != :address_id
|
||||
AND year(ms.datum) = :year
|
||||
AND ms.datum > CURDATE()
|
||||
UNION
|
||||
SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.adresse AS `address_id`,
|
||||
a.name,
|
||||
(CASE
|
||||
WHEN ms.kuerzel LIKE \'%U%\' THEN \'vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%R%\' THEN \'request-vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%L%\' THEN \'remove-vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%K%\' THEN \'sick\'
|
||||
WHEN ms.kuerzel LIKE \'%S%\' THEN \'request-sick\'
|
||||
WHEN ms.kuerzel LIKE \'%V%\' THEN \'remove-sick\'
|
||||
WHEN ms.kuerzel LIKE \'%X%\' THEN \'absent\'
|
||||
WHEN ms.kuerzel LIKE \'%N%\' THEN \'unpaid\'
|
||||
END) AS `type`,
|
||||
ms.urlaubminuten
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON ms.adresse = a.id
|
||||
WHERE ms.kuerzel != \'\' AND ms.kuerzel NOT LIKE \'%C%\' AND ms.kuerzel NOT LIKE \'%J%\'
|
||||
AND ms.adresse = :address_id
|
||||
AND year(ms.datum) = :year
|
||||
) AS `days`
|
||||
INNER JOIN(
|
||||
SELECT DISTINCT
|
||||
ar_groups.adresse
|
||||
FROM `adresse_rolle` AS `ar_groups`
|
||||
WHERE ar_groups.parameter = :group_id
|
||||
AND ar_groups.subjekt = :subject
|
||||
AND (ar_groups.bis = "0000-00-00" OR ar_groups.bis > CURDATE())
|
||||
) AS `ar` ON ar.adresse = days.address_id
|
||||
ORDER BY days.address_id, days.date';
|
||||
|
||||
$results = $this->db->fetchAll(
|
||||
$sql,
|
||||
[
|
||||
'year' => $year,
|
||||
'group_id' => $groupId,
|
||||
'subject' => 'Mitglied',
|
||||
'address_id' => $addressId,
|
||||
]
|
||||
);
|
||||
|
||||
$calendarDatas = [];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $result) {
|
||||
$calendarDatas[] = CalendarData::fromDbState($result);
|
||||
}
|
||||
}
|
||||
|
||||
return $calendarDatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
* @param int $addressId
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return array|CalendarData[]
|
||||
*/
|
||||
public function findAnonymisedVacationCalendarDataByYearAndAddressId(int $year, int $addressId): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
MONTH(days.date) AS `month`,
|
||||
days.date,
|
||||
days.address_id,
|
||||
days.name,
|
||||
days.type,
|
||||
IF(days.urlaubminuten > 0,true,false) AS `is_half`
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.adresse AS `address_id`,
|
||||
a.name,
|
||||
\'away\' AS `type`,
|
||||
ms.urlaubminuten
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON ms.adresse = a.id
|
||||
WHERE (ms.kuerzel LIKE \'%U%\' OR ms.kuerzel LIKE \'%S%\')
|
||||
AND ms.adresse != :address_id
|
||||
AND year(ms.datum) = :year
|
||||
AND ms.datum > CURDATE()
|
||||
UNION
|
||||
SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.adresse AS `address_id`,
|
||||
a.name,
|
||||
(CASE
|
||||
WHEN ms.kuerzel LIKE \'%U%\' THEN \'vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%R%\' THEN \'request-vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%L%\' THEN \'remove-vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%K%\' THEN \'sick\'
|
||||
WHEN ms.kuerzel LIKE \'%S%\' THEN \'request-sick\'
|
||||
WHEN ms.kuerzel LIKE \'%V%\' THEN \'remove-sick\'
|
||||
WHEN ms.kuerzel LIKE \'%X%\' THEN \'absent\'
|
||||
WHEN ms.kuerzel LIKE \'%N%\' THEN \'unpaid\'
|
||||
END) AS `type`,
|
||||
ms.urlaubminuten
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON ms.adresse = a.id
|
||||
WHERE ms.kuerzel != \'\' AND ms.kuerzel NOT LIKE \'%C%\' AND ms.kuerzel NOT LIKE \'%J%\'
|
||||
AND ms.adresse = :address_id
|
||||
AND year(ms.datum) = :year
|
||||
) AS `days`
|
||||
WHERE days.address_id = :address_id
|
||||
ORDER BY days.address_id, days.date';
|
||||
|
||||
$results = $this->db->fetchAll($sql, ['year' => $year, 'address_id' => $addressId]);
|
||||
|
||||
$calendarDatas = [];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $result) {
|
||||
$calendarDatas[] = CalendarData::fromDbState($result);
|
||||
}
|
||||
}
|
||||
|
||||
return $calendarDatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return array|CalendarData[]
|
||||
*/
|
||||
public function findAllVacationCalendarDataByYear(int $year): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
MONTH(days.date) AS `month`,
|
||||
days.date,
|
||||
days.address_id,
|
||||
days.name,
|
||||
days.type,
|
||||
IF(days.urlaubminuten > 0,true,false) AS `is_half`
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.adresse AS `address_id`,
|
||||
a.name,
|
||||
(CASE
|
||||
WHEN ms.kuerzel LIKE \'%U%\' THEN \'vacation\'
|
||||
WHEN ms.kuerzel LIKE \'%K%\' THEN \'sick\'
|
||||
WHEN ms.kuerzel LIKE \'%X%\' THEN \'absent\'
|
||||
WHEN ms.kuerzel LIKE \'%N%\' THEN \'unpaid\'
|
||||
END) AS `type`,
|
||||
ms.urlaubminuten
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON ms.adresse = a.id
|
||||
WHERE (
|
||||
ms.kuerzel LIKE \'%U%\'
|
||||
OR ms.kuerzel LIKE \'%N%\'
|
||||
OR ms.kuerzel LIKE \'%K%\'
|
||||
OR ms.kuerzel LIKE \'%X%\'
|
||||
)
|
||||
AND year(ms.datum) = :year
|
||||
) AS `days`
|
||||
INNER JOIN(
|
||||
SELECT DISTINCT
|
||||
ar_groups.adresse
|
||||
FROM `adresse_rolle` AS `ar_groups`
|
||||
WHERE ar_groups.subjekt = :subject
|
||||
AND (ar_groups.bis = \'0000-00-00\' OR ar_groups.bis > CURDATE())
|
||||
) AS `ar` ON ar.adresse = days.address_id
|
||||
ORDER BY days.date, days.address_id';
|
||||
|
||||
$results = $this->db->fetchAll($sql, ['year' => $year, 'subject' => 'Mitarbeiter']);
|
||||
|
||||
$calendarDatas = [];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $result) {
|
||||
$calendarDatas[] = CalendarData::fromDbState($result);
|
||||
}
|
||||
}
|
||||
|
||||
return $calendarDatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
* @param DateTimeInterface $date
|
||||
*
|
||||
* @return DayInfoData
|
||||
*/
|
||||
public function findDayInfo(int $addressId, DateTimeInterface $date): DayInfoData
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
ms.kuerzel AS `type`,
|
||||
ms.internal_comment AS `internal_comment`,
|
||||
(CASE WEEKDAY(:date)
|
||||
WHEN 0 THEN IFNULL(minutes.vorlagemo,0)
|
||||
WHEN 1 THEN IFNULL(minutes.vorlagedi,0)
|
||||
WHEN 2 THEN IFNULL(minutes.vorlagemi,0)
|
||||
WHEN 3 THEN IFNULL(minutes.vorlagedo,0)
|
||||
WHEN 4 THEN IFNULL(minutes.vorlagefr,0)
|
||||
WHEN 5 THEN IFNULL(minutes.vorlagesa,0)
|
||||
WHEN 6 THEN IFNULL(minutes.vorlageso,0)
|
||||
END) AS `workminutes`,
|
||||
ms.urlaubminuten AS `vacationminutes`
|
||||
FROM (
|
||||
SELECT
|
||||
me.adresse,
|
||||
me.vorlagemo,
|
||||
me.vorlagedi,
|
||||
me.vorlagemi,
|
||||
me.vorlagedo,
|
||||
me.vorlagefr,
|
||||
me.vorlagesa,
|
||||
me.vorlageso
|
||||
FROM `mitarbeiterzeiterfassung_einstellungen` AS `me`
|
||||
WHERE me.adresse = :address_id
|
||||
ORDER BY id DESC
|
||||
LIMIT 1
|
||||
) AS `minutes`
|
||||
LEFT JOIN `mitarbeiterzeiterfassung_sollstunden` AS `ms` ON minutes.adresse = ms.adresse AND ms.datum = :date
|
||||
LIMIT 1';
|
||||
|
||||
$result = $this->db->fetchRow($sql, ['date' => $date->format('Y-m-d'), 'address_id' => $addressId]);
|
||||
|
||||
return DayInfoData::fromDbState($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $requestToken
|
||||
*
|
||||
* @throws InvalidRequestTokenException
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return RequestInfoData
|
||||
*/
|
||||
public function getRequestInfoByToken(string $requestToken): RequestInfoData
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
a.id AS `employee_id`,
|
||||
a.mitarbeiternummer AS `employee_number`,
|
||||
a.name AS `employee_name`,
|
||||
DATE_FORMAT(MIN(ms.datum), \'%d.%m.%Y\') AS `min_date`,
|
||||
DATE_FORMAT(MAX(ms.datum), \'%d.%m.%Y\') AS `max_date`,
|
||||
COUNT(ms.id) AS `amount`,
|
||||
ms.kommentar AS `comment`,
|
||||
ms.kuerzel AS `type`,
|
||||
ms.internal_comment
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
INNER JOIN `adresse` AS `a` ON a.id = ms.adresse
|
||||
WHERE ms.vacation_request_token = :request_token
|
||||
AND (
|
||||
ms.kuerzel LIKE \'%R%\'
|
||||
OR ms.kuerzel LIKE \'%L%\'
|
||||
OR ms.kuerzel LIKE \'%S%\'
|
||||
OR ms.kuerzel LIKE \'%V%\'
|
||||
)
|
||||
GROUP BY ms.vacation_request_token
|
||||
ORDER BY ms.datum';
|
||||
|
||||
$result = $this->db->fetchRow($sql, ['request_token' => $requestToken]);
|
||||
|
||||
if (empty($result)) {
|
||||
throw new InvalidRequestTokenException($requestToken . 'not valid.');
|
||||
}
|
||||
|
||||
return RequestInfoData::fromDbState($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $requestToken
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @throws InvalidRequestTokenException
|
||||
* @return array
|
||||
*/
|
||||
public function getRequestedDaysByToken(string $requestToken): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
ms.datum AS `date`,
|
||||
ms.kuerzel AS `type`
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
WHERE ms.vacation_request_token = :vacation_request_token
|
||||
ORDER BY ms.datum';
|
||||
|
||||
$results = $this->db->fetchAll($sql, ['vacation_request_token' => $requestToken]);
|
||||
|
||||
if (empty($results)) {
|
||||
throw new InvalidRequestTokenException($requestToken . 'not valid.');
|
||||
}
|
||||
|
||||
$formatted = [];
|
||||
foreach ($results as $result) {
|
||||
try {
|
||||
$formatted[] = ['date' => new DateTimeImmutable($result['date']), 'type' => $result['type']];
|
||||
} catch (Exception $e) {
|
||||
throw new InvalidDateFormatException('Could not convert date: ' . $result['date']);
|
||||
}
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $daysTillDeletion
|
||||
* @param int $addressId
|
||||
*
|
||||
* @throws InvalidDateFormatException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function findRejectedDays(int $daysTillDeletion, int $addressId): array
|
||||
{
|
||||
$sql =
|
||||
'SELECT
|
||||
ms.datum AS `date`
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
WHERE (ms.kuerzel LIKE \'%J%\' OR ms.kuerzel LIKE \'%C%\')
|
||||
AND ms.adresse = :address_id
|
||||
AND DATE_ADD(FROM_UNIXTIME(ms.vacation_request_token), INTERVAL :days_till_deletion DAY) < CURDATE()';
|
||||
|
||||
$results = $this->db->fetchAll(
|
||||
$sql,
|
||||
[
|
||||
'days_till_deletion' => $daysTillDeletion,
|
||||
'address_id' => $addressId,
|
||||
]
|
||||
);
|
||||
|
||||
$formatted = [];
|
||||
if (!empty($results)) {
|
||||
foreach ($results as $result) {
|
||||
try {
|
||||
$formatted[] = ['date' => new DateTimeImmutable($result['date'])];
|
||||
} catch (Exception $e) {
|
||||
throw new InvalidDateFormatException('Could not convert date: ' . $result['date']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function findAmountRequestedVacation(int $addressId): float
|
||||
{
|
||||
$sql =
|
||||
'SELECT SUM(info.amount) AS `amount`
|
||||
FROM(
|
||||
SELECT
|
||||
count(ms.id) AS `amount`
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
WHERE ms.adresse = :address_id
|
||||
AND ms.urlaubminuten = 0
|
||||
AND ms.kuerzel LIKE \'%R%\'
|
||||
UNION
|
||||
SELECT
|
||||
count(ms.id) / 2 AS `amount`
|
||||
FROM `mitarbeiterzeiterfassung_sollstunden` AS `ms`
|
||||
WHERE ms.adresse = :address_id
|
||||
AND ms.urlaubminuten > 0
|
||||
AND ms.kuerzel LIKE \'%R%\'
|
||||
) AS `info`';
|
||||
|
||||
$result = $this->db->fetchRow($sql, ['address_id' => $addressId]);
|
||||
|
||||
if (!empty($result)) {
|
||||
return (float)$result['amount'];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\TimeManagement\Service;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Xentral\Components\Database\Database;
|
||||
use Xentral\Modules\TimeManagement\Exception\InvalidQueryException;
|
||||
|
||||
final class TimeManagementTargetHourService
|
||||
{
|
||||
|
||||
/** @var Database $db */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* @param Database $db
|
||||
*/
|
||||
public function __construct(Database $db)
|
||||
{
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $vacationRequestToken
|
||||
* @param string $internalComment
|
||||
*
|
||||
*/
|
||||
public function saveInternalComment(string $vacationRequestToken, string $internalComment): void
|
||||
{
|
||||
$sql =
|
||||
'UPDATE `mitarbeiterzeiterfassung_sollstunden` SET
|
||||
`internal_comment` = :internal_comment
|
||||
WHERE `vacation_request_token` = :vacation_request_token';
|
||||
|
||||
$this->db->perform(
|
||||
$sql,
|
||||
[
|
||||
'vacation_request_token' => $vacationRequestToken,
|
||||
'internal_comment' => $internalComment,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
* @param DateTimeInterface $date
|
||||
* @param string $oldType
|
||||
* @param string $newType
|
||||
*
|
||||
*/
|
||||
public function updateTargetHourType(
|
||||
int $addressId,
|
||||
DateTimeInterface $date,
|
||||
string $oldType,
|
||||
string $newType
|
||||
): void {
|
||||
$sql =
|
||||
'UPDATE `mitarbeiterzeiterfassung_sollstunden` SET
|
||||
`kuerzel` = REPLACE(`kuerzel`,:old_type, :new_type)
|
||||
WHERE `adresse` = :address_id
|
||||
AND `datum` = :date';
|
||||
|
||||
$numAffected = (int)$this->db->fetchAffected(
|
||||
$sql,
|
||||
[
|
||||
'old_type' => $oldType,
|
||||
'new_type' => $newType,
|
||||
'address_id' => $addressId,
|
||||
'date' => $date->format('Y-m-d'),
|
||||
]
|
||||
);
|
||||
|
||||
if ($numAffected == 0) {
|
||||
throw new InvalidQueryException(
|
||||
'Target hour could not be updated. Maybe wrong arguments. addressId: ' . $addressId .
|
||||
', dateString: ' . $date->format('Y-m-d') .
|
||||
', oldType: ' . $oldType .
|
||||
', newType: ' . $newType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $addressId
|
||||
* @param DateTimeInterface $date
|
||||
* @param string $requestToken
|
||||
*
|
||||
* @throws InvalidQueryException
|
||||
*/
|
||||
public function updateVacationRequestToken(int $addressId, DateTimeInterface $date, string $requestToken): void
|
||||
{
|
||||
$sql =
|
||||
'UPDATE `mitarbeiterzeiterfassung_sollstunden` SET
|
||||
`vacation_request_token` = :vacation_request_token
|
||||
WHERE `adresse` = :address_id
|
||||
AND `datum` = :date';
|
||||
|
||||
$numAffected = (int)$this->db->fetchAffected(
|
||||
$sql,
|
||||
[
|
||||
'vacation_request_token' => $requestToken,
|
||||
'address_id' => $addressId,
|
||||
'date' => $date->format('Y-m-d'),
|
||||
]
|
||||
);
|
||||
|
||||
if ($numAffected == 0) {
|
||||
throw new InvalidQueryException(
|
||||
'Target hour could not be updated. Maybe wrong arguments. addressId: ' . $addressId .
|
||||
', dateString: ' . $date->format('Y-m-d') .
|
||||
', requestToken: ' . $requestToken
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user