diff --git a/src/Entity/Timesheet.php b/src/Entity/Timesheet.php index 80e80a88..de70c97d 100644 --- a/src/Entity/Timesheet.php +++ b/src/Entity/Timesheet.php @@ -572,7 +572,7 @@ class Timesheet implements EntityWithMetaFields, ExportItemInterface /** * @return string */ - public function getTimezone(): string + public function getTimezone(): ?string { return $this->timezone; } diff --git a/src/Timesheet/TimesheetService.php b/src/Timesheet/TimesheetService.php index 801d98e9..75f99b94 100644 --- a/src/Timesheet/TimesheetService.php +++ b/src/Timesheet/TimesheetService.php @@ -148,6 +148,7 @@ final class TimesheetService $this->repository->begin(); try { $this->validateTimesheet($timesheet); + $this->fixTimezone($timesheet); $this->dispatcher->dispatch(new TimesheetCreatePreEvent($timesheet)); $this->repository->save($timesheet); @@ -187,6 +188,8 @@ final class TimesheetService } */ + $this->fixTimezone($timesheet); + $this->dispatcher->dispatch(new TimesheetUpdatePreEvent($timesheet)); $this->repository->save($timesheet); $this->dispatcher->dispatch(new TimesheetUpdatePostEvent($timesheet)); @@ -263,6 +266,21 @@ final class TimesheetService } } + /** + * Makes sure, that the timesheet record has the timezone of the user. + * + * This fixes #1442 and prevents a wrong time if a teamlead edits the + * timesheet for an employee living in another timezone. + * + * @param Timesheet $timesheet + */ + private function fixTimezone(Timesheet $timesheet) + { + if (null !== ($timezone = $timesheet->getTimezone()) && $timezone !== $timesheet->getUser()->getTimezone()) { + $timesheet->setTimezone($timesheet->getUser()->getTimezone()); + } + } + /** * Stops active records if more than allowed are running for the timesheet user. * diff --git a/tests/Timesheet/TimesheetServiceTest.php b/tests/Timesheet/TimesheetServiceTest.php index 47cc2dda..6873c174 100644 --- a/tests/Timesheet/TimesheetServiceTest.php +++ b/tests/Timesheet/TimesheetServiceTest.php @@ -11,6 +11,7 @@ namespace App\Tests\Timesheet; use App\Configuration\TimesheetConfiguration; use App\Entity\Timesheet; +use App\Entity\User; use App\Event\TimesheetCreatePostEvent; use App\Event\TimesheetCreatePreEvent; use App\Event\TimesheetDeleteMultiplePreEvent; @@ -138,6 +139,50 @@ class TimesheetServiceTest extends TestCase $sut->saveNewTimesheet($newTimesheet); } + public function testSaveNewTimesheetFixesTimezone() + { + $user = new User(); + $user->setTimezone('Europe/Paris'); + + $begin = new \DateTime('now', new \DateTimeZone('Africa/Casablanca')); + $timesheet = new Timesheet(); + + $timesheet->setBegin($begin); + self::assertEquals('Africa/Casablanca', $timesheet->getTimezone()); + + $timesheet->setUser($user); + self::assertEquals('Africa/Casablanca', $timesheet->getTimezone()); + + $authorizationChecker = $this->createMock(AuthorizationCheckerInterface::class); + $authorizationChecker->expects($this->once())->method('isGranted')->willReturn(true); + $sut = $this->getSut($authorizationChecker); + + $sut->saveNewTimesheet($timesheet); + + self::assertEquals('Europe/Paris', $timesheet->getTimezone()); + } + + public function testUpdateTimesheetFixesTimezone() + { + $user = new User(); + $user->setTimezone('Europe/Paris'); + + $begin = new \DateTime('now', new \DateTimeZone('Africa/Casablanca')); + $timesheet = new Timesheet(); + + $timesheet->setBegin($begin); + self::assertEquals('Africa/Casablanca', $timesheet->getTimezone()); + + $timesheet->setUser($user); + self::assertEquals('Africa/Casablanca', $timesheet->getTimezone()); + + $sut = $this->getSut(); + + $sut->updateTimesheet($timesheet); + + self::assertEquals('Europe/Paris', $timesheet->getTimezone()); + } + public function testCannotRestartedPersistedTimesheet() { $timesheet = $this->createMock(Timesheet::class);