@@ -606,7 +606,7 @@ export default class KimaiCalendar {
|
||||
<li>` + this.options['translations']['activity'] + `: ` + escaper.escapeForHtml(eventObj.activity) + `</li>
|
||||
</ul>` +
|
||||
(eventObj.description !== null || eventObj.tags.length > 0 ? '<hr>' : '') +
|
||||
(eventObj.description ? '<p>' + escaper.escapeForHtml(eventObj.description) + '</p>' : '') + tags + `
|
||||
(eventObj.description ? '<div>' + escaper.escapeForHtml(eventObj.description) + '</div>' : '') + tags + `
|
||||
</div>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
div {
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
|
||||
.draggable {
|
||||
|
||||
@@ -78,6 +78,7 @@ tabler:
|
||||
filter: fas fa-filter
|
||||
help: far fa-question-circle
|
||||
home: fas fa-home
|
||||
info: fas fa-info-circle
|
||||
import: fas fa-file-import
|
||||
invoice: fas fa-file-contract
|
||||
invoice-template: fas fa-file-signature
|
||||
@@ -99,6 +100,7 @@ tabler:
|
||||
password: fas fa-key
|
||||
pause: fas fa-pause
|
||||
pause-small: far fa-pause-circle
|
||||
pending: fas fa-hourglass-half
|
||||
pin: fas fa-thumbtack
|
||||
pdf: fas fa-file-pdf
|
||||
permissions: fas fa-user-lock
|
||||
@@ -112,6 +114,7 @@ tabler:
|
||||
reporting: far fa-chart-bar
|
||||
report: far fa-chart-bar
|
||||
review: fas fa-user-check
|
||||
rejected: fas fa-ban
|
||||
right: fas fa-chevron-right
|
||||
right2: fas fa-angle-double-right
|
||||
roles: fas fa-user-shield
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@
|
||||
"/build/app.99c7b6b4.js"
|
||||
],
|
||||
"css": [
|
||||
"/build/app.a61c91dc.css"
|
||||
"/build/app.f82609fb.css"
|
||||
]
|
||||
},
|
||||
"export-pdf": {
|
||||
@@ -45,7 +45,7 @@
|
||||
"calendar": {
|
||||
"js": [
|
||||
"/build/runtime.f0079159.js",
|
||||
"/build/calendar.25b368b9.js"
|
||||
"/build/calendar.e7b6fa49.js"
|
||||
],
|
||||
"css": [
|
||||
"/build/calendar.bb473428.css"
|
||||
@@ -64,7 +64,7 @@
|
||||
"integrity": {
|
||||
"/build/runtime.f0079159.js": "sha384-H22sAW1aTvyIPqvHOvGXWSWTxf0y6mptp+MsVmyXCfjx/WJjBbhX9gbUZ+qIuihV",
|
||||
"/build/app.99c7b6b4.js": "sha384-bPAdOMl3I6Ia3clnHgDiwoNKKe/bKnAdHUJdl7BXbsFNMg2wHsUDrGH+uNCQowqM",
|
||||
"/build/app.a61c91dc.css": "sha384-7rtbsyyUucsBktCZZXFuqnSHX0cvCWQ0KQgHpolGcWlFhaIEPn+ipnOc5yySeYwT",
|
||||
"/build/app.f82609fb.css": "sha384-X848pib0qXUB72LdaVSupYXnYPE/lNXHXNkJdlh4FRj534BVHyupi+ly3cfCkDRS",
|
||||
"/build/export-pdf.d367a32e.js": "sha384-Z5baqnzjI636nYFs4g63ViIKBZKRW4Jhv/7PQmTEQlqhfA7eK0vUMUtiyy0R5A9u",
|
||||
"/build/export-pdf.d8a6c23b.css": "sha384-ztepocHE4rnGE9eKZ4kL6jTKaePUyiwiB9TjJjstjpf/ckcKg1HedrEOOk/8ElJg",
|
||||
"/build/invoice.2604495e.js": "sha384-D6JvhGSqlx7z72b/qD3nF3QDXPy+XsCSRGtWfs1icjDKOcd2UzuXwuSa/E1Fg2TJ",
|
||||
@@ -72,7 +72,7 @@
|
||||
"/build/invoice-pdf.ce9aace0.js": "sha384-mtZkXrpsXFMX2YvmmTlCm91QgsTlZLzLJnDAFcTuBDtDZ7TNkqLYkfCeLzFLVfwb",
|
||||
"/build/invoice-pdf.2b749265.css": "sha384-DXXgkz2WWnrWnfBnXX5fmfPQSPb98upMnWxYKwTGYS04EhrPIWfDCutB2unIrWh7",
|
||||
"/build/chart.f5becfac.js": "sha384-GSqETm8wULiVXyizvwRompfwu63r/C0Qd/AvrHDE4cqAKiIGCssb3QyBtGu1WN+W",
|
||||
"/build/calendar.25b368b9.js": "sha384-jKqj+OqQVIm8TXCEmnRveqG3348yVwvlb0k88kRn90DZGzbthjToMHUb5pwL/TtI",
|
||||
"/build/calendar.e7b6fa49.js": "sha384-/lbV1KHFBLr1Y/aaY7Pfckynm/EAcZqBwJQdxum3gvbDVdcthoxPSNTvf++vKadj",
|
||||
"/build/calendar.bb473428.css": "sha384-900W9o8666Qpw21rLP7hn5Ql8tWd40k0IcE3QpFm7E7V6bKva7xQgGlyzVuuh4GK",
|
||||
"/build/dashboard.6774a712.js": "sha384-lBwkNqUPv+IBbznagiFakY2BOIueq/Bg89wHO2XeM9YAZ51rPkrvdMd+XmFupHsM",
|
||||
"/build/dashboard.18f5a8b7.css": "sha384-PBD8ftb2yBoSjRe2sN5Xb4dEz045kOEUfcIufdSis+tWoWdAx5j4Yic+F/6CYbrP"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"build/app.css": "/build/app.a61c91dc.css",
|
||||
"build/app.css": "/build/app.f82609fb.css",
|
||||
"build/app.js": "/build/app.99c7b6b4.js",
|
||||
"build/export-pdf.css": "/build/export-pdf.d8a6c23b.css",
|
||||
"build/export-pdf.js": "/build/export-pdf.d367a32e.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"build/invoice-pdf.js": "/build/invoice-pdf.ce9aace0.js",
|
||||
"build/chart.js": "/build/chart.f5becfac.js",
|
||||
"build/calendar.css": "/build/calendar.bb473428.css",
|
||||
"build/calendar.js": "/build/calendar.25b368b9.js",
|
||||
"build/calendar.js": "/build/calendar.e7b6fa49.js",
|
||||
"build/dashboard.css": "/build/dashboard.18f5a8b7.css",
|
||||
"build/dashboard.js": "/build/dashboard.6774a712.js",
|
||||
"build/runtime.js": "/build/runtime.f0079159.js"
|
||||
|
||||
@@ -17,11 +17,11 @@ class Constants
|
||||
/**
|
||||
* The current release version
|
||||
*/
|
||||
public const VERSION = '2.0.27';
|
||||
public const VERSION = '2.0.28';
|
||||
/**
|
||||
* The current release: major * 10000 + minor * 100 + patch
|
||||
*/
|
||||
public const VERSION_ID = 20027;
|
||||
public const VERSION_ID = 20028;
|
||||
/**
|
||||
* The software name
|
||||
*/
|
||||
|
||||
@@ -33,6 +33,7 @@ final class ContractController extends AbstractController
|
||||
$dateTimeFactory = $this->getDateTimeFactory($currentUser);
|
||||
$canChangeUser = $this->isGranted('contract_other_profile');
|
||||
$defaultDate = $dateTimeFactory->createStartOfYear();
|
||||
$now = $dateTimeFactory->createDateTime();
|
||||
|
||||
$values = new YearByUser();
|
||||
$values->setUser($currentUser);
|
||||
@@ -62,7 +63,7 @@ final class ContractController extends AbstractController
|
||||
|
||||
/** @var \DateTime $yearDate */
|
||||
$yearDate = $values->getDate();
|
||||
$year = $workingTimeService->getYear($profile, $yearDate);
|
||||
$year = $workingTimeService->getYear($profile, $yearDate, $now);
|
||||
|
||||
$page = new PageSetup('work_times');
|
||||
$page->setHelp('contract.html');
|
||||
@@ -73,7 +74,6 @@ final class ContractController extends AbstractController
|
||||
$controllerEvent = new WorkContractDetailControllerEvent($year);
|
||||
$eventDispatcher->dispatch($controllerEvent);
|
||||
|
||||
$now = $dateTimeFactory->createDateTime();
|
||||
$summary = $workingTimeService->getYearSummary($year, $now);
|
||||
|
||||
$boxConfiguration = new BoxConfiguration();
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace App\Controller;
|
||||
use App\Configuration\LocaleService;
|
||||
use App\Entity\User;
|
||||
use App\Event\ConfigureMainMenuEvent;
|
||||
use App\Repository\UserRepository;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -28,7 +29,7 @@ final class HomepageController extends AbstractController
|
||||
public const DEFAULT_ROUTE = 'timesheet';
|
||||
|
||||
#[Route(path: '', defaults: [], name: 'homepage', methods: ['GET'])]
|
||||
public function indexAction(Request $request, LocaleService $service, EventDispatcherInterface $eventDispatcher): Response
|
||||
public function homepage(Request $request, LocaleService $service, EventDispatcherInterface $eventDispatcher, UserRepository $userRepository): Response
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$userLanguage = $user->getLanguage();
|
||||
@@ -72,8 +73,13 @@ final class HomepageController extends AbstractController
|
||||
try {
|
||||
return $this->redirectToRoute($route, ['_locale' => $language]);
|
||||
} catch (\Exception $ex) {
|
||||
if ($route === $userRoute) {
|
||||
// fix invalid routes from old plugins / versions
|
||||
$user->setPreferenceValue('login_initial_view', 'dashboard');
|
||||
$userRepository->saveUser($user);
|
||||
} else {
|
||||
$this->logException($ex);
|
||||
// something is wrong with the url parameters ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,9 +60,12 @@ final class ProfileController extends AbstractController
|
||||
{
|
||||
$dateFactory = $this->getDateTimeFactory();
|
||||
$userStats = $repository->getUserStatistics($profile);
|
||||
$firstEntry = $statisticService->findFirstRecordDate($profile);
|
||||
$workStartingDay = $profile->getWorkStartingDay();
|
||||
if ($workStartingDay === null) {
|
||||
$workStartingDay = $statisticService->findFirstRecordDate($profile);
|
||||
}
|
||||
|
||||
$begin = $firstEntry ?? $dateFactory->getStartOfMonth();
|
||||
$begin = $workStartingDay ?? $dateFactory->getStartOfMonth();
|
||||
$end = $dateFactory->getEndOfMonth();
|
||||
|
||||
// statistic service does not fill up the complete year by default!
|
||||
@@ -73,7 +76,7 @@ final class ProfileController extends AbstractController
|
||||
'tab' => 'charts',
|
||||
'user' => $profile,
|
||||
'stats' => $userStats,
|
||||
'firstTimesheet' => $firstEntry,
|
||||
'workingSince' => $workStartingDay,
|
||||
'workMonths' => $statisticService->getMonthlyStats($begin, $end, [$profile])[0]
|
||||
];
|
||||
|
||||
|
||||
@@ -1174,6 +1174,27 @@ class User implements UserInterface, EquatableInterface, ThemeUserInterface, Pas
|
||||
return (int) $this->getPreferenceValue(UserPreference::WORK_HOURS_SUNDAY, 0);
|
||||
}
|
||||
|
||||
public function getWorkStartingDay(): ?\DateTimeInterface
|
||||
{
|
||||
$date = $this->getPreferenceValue(UserPreference::WORK_STARTING_DAY);
|
||||
|
||||
if ($date === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$date = \DateTimeImmutable::createFromFormat('Y-m-d h:i:s', $date . ' 00:00:00', new \DateTimeZone($this->getTimezone()));
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
|
||||
return ($date instanceof \DateTimeInterface) ? $date : null;
|
||||
}
|
||||
|
||||
public function setWorkStartingDay(?\DateTimeInterface $date): void
|
||||
{
|
||||
$this->setPreferenceValue(UserPreference::WORK_STARTING_DAY, $date?->format('Y-m-d'));
|
||||
}
|
||||
|
||||
public function getPublicHolidayGroup(): null|string
|
||||
{
|
||||
$group = $this->getPreferenceValue(UserPreference::PUBLIC_HOLIDAY_GROUP);
|
||||
|
||||
@@ -38,6 +38,7 @@ class UserPreference
|
||||
public const WORK_HOURS_FRIDAY = 'work_friday';
|
||||
public const WORK_HOURS_SATURDAY = 'work_saturday';
|
||||
public const WORK_HOURS_SUNDAY = 'work_sunday';
|
||||
public const WORK_STARTING_DAY = 'work_start_day';
|
||||
public const PUBLIC_HOLIDAY_GROUP = 'public_holiday_group';
|
||||
public const HOLIDAYS_PER_YEAR = 'holidays';
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ final class ConfigureMainMenuEvent extends Event
|
||||
private MenuItemModel $apps;
|
||||
private MenuItemModel $admin;
|
||||
private MenuItemModel $system;
|
||||
private ?MenuItemModel $root = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -33,15 +32,23 @@ final class ConfigureMainMenuEvent extends Event
|
||||
|
||||
public function findById(string $identifier): ?MenuItemModel
|
||||
{
|
||||
if ($this->root === null) {
|
||||
$this->root = new MenuItemModel('root', 'root');
|
||||
$this->root->addChild($this->menu);
|
||||
$this->root->addChild($this->apps);
|
||||
$this->root->addChild($this->admin);
|
||||
$this->root->addChild($this->system);
|
||||
if (($tmp = $this->menu->findChild($identifier)) !== null) {
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
return $this->root->findChild($identifier);
|
||||
if (($tmp = $this->apps->findChild($identifier)) !== null) {
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
if (($tmp = $this->admin->findChild($identifier)) !== null) {
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
if (($tmp = $this->system->findChild($identifier)) !== null) {
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMenu(): MenuItemModel
|
||||
|
||||
@@ -12,12 +12,21 @@ namespace App\Event;
|
||||
use App\WorkingTime\Model\Year;
|
||||
use Symfony\Contracts\EventDispatcher\Event;
|
||||
|
||||
/**
|
||||
* Working time for every day of the given year.
|
||||
* Will be reflected in the working-time summary row.
|
||||
*/
|
||||
final class WorkingTimeYearEvent extends Event
|
||||
{
|
||||
public function __construct(private Year $year)
|
||||
public function __construct(private Year $year, private \DateTimeInterface $until)
|
||||
{
|
||||
}
|
||||
|
||||
public function getUntil(): \DateTimeInterface
|
||||
{
|
||||
return $this->until;
|
||||
}
|
||||
|
||||
public function getYear(): Year
|
||||
{
|
||||
return $this->year;
|
||||
|
||||
@@ -15,8 +15,8 @@ use App\Model\Day as BaseDay;
|
||||
final class Day extends BaseDay
|
||||
{
|
||||
private ?WorkingTime $workingTime = null;
|
||||
/** @var array<string, int> */
|
||||
private array $descriptions = [];
|
||||
/** @var array<DayAddon> */
|
||||
private array $addons = [];
|
||||
|
||||
public function isLocked(): bool
|
||||
{
|
||||
@@ -38,18 +38,27 @@ final class Day extends BaseDay
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, int>
|
||||
* @return array<DayAddon>
|
||||
*/
|
||||
public function getDescriptions(): array
|
||||
public function getAddons(): array
|
||||
{
|
||||
return $this->descriptions;
|
||||
return $this->addons;
|
||||
}
|
||||
|
||||
public function hasAddons(): bool
|
||||
{
|
||||
return \count($this->addons) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Descriptions show up in the approval PDF and maybe in other places as well.
|
||||
*/
|
||||
public function addDescription(string $description, int $duration): void
|
||||
public function addAddon(DayAddon $addon): void
|
||||
{
|
||||
$this->descriptions[$description] = $duration;
|
||||
$this->addons[] = $addon;
|
||||
|
||||
if (!$this->isLocked() && $this->workingTime !== null) {
|
||||
$this->workingTime->setActualTime($this->workingTime->getActualTime() + $addon->getDuration());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
43
src/WorkingTime/Model/DayAddon.php
Normal file
43
src/WorkingTime/Model/DayAddon.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\WorkingTime\Model;
|
||||
|
||||
final class DayAddon
|
||||
{
|
||||
private string $title;
|
||||
private int $duration;
|
||||
private bool $billable = true;
|
||||
|
||||
public function __construct(string $title, int $duration)
|
||||
{
|
||||
$this->title = $title;
|
||||
$this->duration = $duration;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function getDuration(): int
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
public function isBillable(): bool
|
||||
{
|
||||
return $this->billable;
|
||||
}
|
||||
|
||||
public function setBillable(bool $billable): void
|
||||
{
|
||||
$this->billable = $billable;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,16 @@ use App\Model\Month as BaseMonth;
|
||||
*/
|
||||
final class Month extends BaseMonth
|
||||
{
|
||||
public function __construct(\DateTimeInterface $month, private User $user)
|
||||
{
|
||||
parent::__construct($month);
|
||||
}
|
||||
|
||||
public function getUser(): User
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* A month is only locked IF every day is approved.
|
||||
* If there is even one day left open, the entire month is not locked.
|
||||
|
||||
@@ -30,7 +30,7 @@ final class Year extends BaseYear
|
||||
|
||||
protected function createMonth(\DateTimeInterface $month): Month
|
||||
{
|
||||
return new Month($month);
|
||||
return new Month($month, $this->user);
|
||||
}
|
||||
|
||||
public function getExpectedTime(\DateTimeInterface $until): int
|
||||
|
||||
@@ -46,7 +46,7 @@ final class WorkingTimeService
|
||||
return $this->workingTimeRepository->getLatestApproval($user);
|
||||
}
|
||||
|
||||
public function getYear(User $user, \DateTimeInterface $yearDate): Year
|
||||
public function getYear(User $user, \DateTimeInterface $yearDate, \DateTimeInterface $until): Year
|
||||
{
|
||||
$yearTimes = $this->workingTimeRepository->findForYear($user, $yearDate);
|
||||
$existing = [];
|
||||
@@ -57,6 +57,7 @@ final class WorkingTimeService
|
||||
$year = new Year(\DateTimeImmutable::createFromInterface($yearDate), $user);
|
||||
|
||||
$stats = null;
|
||||
$firstDay = $user->getWorkStartingDay();
|
||||
|
||||
foreach ($year->getMonths() as $month) {
|
||||
foreach ($month->getDays() as $day) {
|
||||
@@ -70,8 +71,12 @@ final class WorkingTimeService
|
||||
$stats = $this->getYearStatistics($yearDate, $user);
|
||||
}
|
||||
|
||||
$result = new WorkingTime($user, $day->getDay());
|
||||
$result->setExpectedTime($user->getWorkHoursForDay($day->getDay()));
|
||||
$dayDate = $day->getDay();
|
||||
$result = new WorkingTime($user, $dayDate);
|
||||
|
||||
if ($firstDay === null || $firstDay <= $dayDate) {
|
||||
$result->setExpectedTime($user->getWorkHoursForDay($dayDate));
|
||||
}
|
||||
|
||||
if (\array_key_exists($key, $stats)) {
|
||||
$result->setActualTime($stats[$key]);
|
||||
@@ -81,16 +86,16 @@ final class WorkingTimeService
|
||||
}
|
||||
}
|
||||
|
||||
$event = new WorkingTimeYearEvent($year);
|
||||
$event = new WorkingTimeYearEvent($year, $until);
|
||||
$this->eventDispatcher->dispatch($event);
|
||||
|
||||
return $year;
|
||||
}
|
||||
|
||||
public function getMonth(User $user, \DateTimeInterface $monthDate): Month
|
||||
public function getMonth(User $user, \DateTimeInterface $monthDate, \DateTimeInterface $until): Month
|
||||
{
|
||||
// uses the year, because that triggers the required events to collect all different working times
|
||||
$year = $this->getYear($user, $monthDate);
|
||||
$year = $this->getYear($user, $monthDate, $until);
|
||||
|
||||
return $year->getMonth($monthDate);
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
</td>
|
||||
{% set dayCount = 0 %}
|
||||
{% for day in month.days %}
|
||||
{% set class = 'text-end contractDay' %}
|
||||
{% set class = 'text-end contractDay text-nowrap' %}
|
||||
{% if day.day is weekend %}
|
||||
{% set class = class ~ ' weekend' %}
|
||||
{% endif %}
|
||||
@@ -223,6 +223,16 @@
|
||||
{% endif %}
|
||||
<td class="{{ class }}">
|
||||
{% if (day.workingTime.expectedTime != 0 or day.workingTime.actualTime != 0) and (now > day.day or day.workingTime.actualTime > 0) %}
|
||||
{% if day.hasAddons() %}
|
||||
{% set statusTitle = '' %}
|
||||
{% for addon in day.getAddons() %}
|
||||
{% set statusTitle = statusTitle ~ (addon.title|trans) ~ ' (' ~ addon.duration|duration(decimal) ~ ')' %}
|
||||
{% if not loop.last %}
|
||||
{% set statusTitle = statusTitle ~ '<br>' %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<span class="status-dot status-azure" data-toggle="tooltip" data-placement="top" title="{{ statusTitle }}"></span>
|
||||
{% endif %}
|
||||
{{ work_times_result(day.workingTime.expectedTime, day.workingTime.actualTime, decimal) }}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
}) %}
|
||||
{% endif %}
|
||||
{% set datagrid = datagrid|merge({
|
||||
'profile.first_entry' : (firstTimesheet is not null ? firstTimesheet|date_short : '–'),
|
||||
'profile.first_entry' : (workingSince is not null ? workingSince|date_short : '–'),
|
||||
'profile.registration_date' : user.registeredAt|date_short,
|
||||
}) %}
|
||||
{% set seeOwnRate = false %}
|
||||
|
||||
@@ -18,7 +18,7 @@ use PHPUnit\Framework\TestCase;
|
||||
*/
|
||||
class ConfigureMainMenuEventTest extends TestCase
|
||||
{
|
||||
public function testGetterAndSetter()
|
||||
public function testGetterAndSetter(): void
|
||||
{
|
||||
$sut = new ConfigureMainMenuEvent();
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ class WorkingTimeYearEventTest extends TestCase
|
||||
$user = new User();
|
||||
$date = new \DateTime('2023-02-10');
|
||||
$year = new Year($date, $user);
|
||||
$sut = new WorkingTimeYearEvent($year);
|
||||
$sut = new WorkingTimeYearEvent($year, clone $date);
|
||||
|
||||
self::assertSame($year, $sut->getYear());
|
||||
self::assertEquals('2023-02-10', $sut->getUntil()->format('Y-m-d'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,15 @@ class MonthTest extends TestCase
|
||||
{
|
||||
public function testDefaults(): void
|
||||
{
|
||||
$user = new User();
|
||||
$user->setUsername('foo-bar');
|
||||
|
||||
$months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
foreach($months as $key => $days) {
|
||||
$index = ++$key;
|
||||
$monthKey = ($index < 10) ? '0' . $index : $index;
|
||||
$date = new \DateTimeImmutable(sprintf('2020-%s-25 13:00:00', $monthKey));
|
||||
$month = new Month($date);
|
||||
$month = new Month($date, $user);
|
||||
self::assertEquals(sprintf('2020-%s-25', $monthKey), $month->getMonth()->format('Y-m-d'));
|
||||
self::assertCount($days, $month->getDays());
|
||||
self::assertFalse($month->isLocked());
|
||||
|
||||
@@ -4982,11 +4982,6 @@ parameters:
|
||||
count: 1
|
||||
path: Event/CalendarGoogleSourceEventTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Event\\\\ConfigureMainMenuEventTest\\:\\:testGetterAndSetter\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Event/ConfigureMainMenuEventTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Event\\\\CustomerMetaDefinitionEventTest\\:\\:testGetterAndSetter\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
|
||||
Reference in New Issue
Block a user