fix sunday being first day of week (#2483)
This commit is contained in:
@@ -30,6 +30,6 @@ abstract class BaseApiController extends AbstractController
|
||||
$user = $this->getUser();
|
||||
}
|
||||
|
||||
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()));
|
||||
return DateTimeFactory::createByUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ class InvoiceCreateCommand extends Command
|
||||
}
|
||||
|
||||
$timezone = new \DateTimeZone($timezone);
|
||||
$dateFactory = new DateTimeFactory($timezone);
|
||||
$dateFactory = new DateTimeFactory($timezone, $user->isFirstDayOfWeekSunday());
|
||||
|
||||
if (!empty($input->getOption('start')) && empty($input->getOption('end'))) {
|
||||
$io->error('You need to supply a end date if a start date was given');
|
||||
|
||||
@@ -165,7 +165,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv
|
||||
$user = $this->getUser();
|
||||
}
|
||||
|
||||
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()));
|
||||
return DateTimeFactory::createByUser($user);
|
||||
}
|
||||
|
||||
protected function getLocaleFormats(string $locale): LocaleFormats
|
||||
|
||||
@@ -69,6 +69,7 @@ class User extends BaseUser implements UserInterface
|
||||
public const ROLE_USER = 'ROLE_USER';
|
||||
public const ROLE_TEAMLEAD = 'ROLE_TEAMLEAD';
|
||||
public const ROLE_ADMIN = 'ROLE_ADMIN';
|
||||
//public const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
|
||||
|
||||
public const DEFAULT_ROLE = self::ROLE_USER;
|
||||
public const DEFAULT_LANGUAGE = Constants::DEFAULT_LOCALE;
|
||||
@@ -370,6 +371,11 @@ class User extends BaseUser implements UserInterface
|
||||
$this->setPreferenceValue(UserPreference::LOCALE, $language);
|
||||
}
|
||||
|
||||
public function isFirstDayOfWeekSunday(): bool
|
||||
{
|
||||
return $this->getFirstDayOfWeek() === 'sunday';
|
||||
}
|
||||
|
||||
public function getFirstDayOfWeek(): string
|
||||
{
|
||||
return $this->getPreferenceValue(UserPreference::FIRST_WEEKDAY, User::DEFAULT_FIRST_WEEKDAY);
|
||||
|
||||
@@ -294,12 +294,14 @@ final class ServiceInvoice
|
||||
private function getDateTimeFactory(InvoiceQuery $query): DateTimeFactory
|
||||
{
|
||||
$timezone = date_default_timezone_get();
|
||||
$sunday = false;
|
||||
|
||||
if (null !== $query->getCurrentUser()) {
|
||||
$timezone = $query->getCurrentUser()->getTimezone();
|
||||
if (null !== ($user = $query->getCurrentUser())) {
|
||||
$timezone = $user->getTimezone();
|
||||
$sunday = $user->isFirstDayOfWeekSunday();
|
||||
}
|
||||
|
||||
return new DateTimeFactory(new \DateTimeZone($timezone));
|
||||
return new DateTimeFactory(new \DateTimeZone($timezone), $sunday);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,6 @@ use App\Repository\ProjectRepository;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Timesheet\DateTimeFactory;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
|
||||
final class ProjectStatisticService
|
||||
@@ -132,7 +131,7 @@ final class ProjectStatisticService
|
||||
*/
|
||||
public function getProjectView(User $user, array $projects, ?DateTime $today = null): array
|
||||
{
|
||||
$factory = new DateTimeFactory(new DateTimeZone($user->getTimezone()));
|
||||
$factory = DateTimeFactory::createByUser($user);
|
||||
if (null === $today) {
|
||||
$today = $factory->createDateTime();
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\Timesheet;
|
||||
|
||||
use App\Entity\User;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
|
||||
@@ -18,16 +19,26 @@ class DateTimeFactory
|
||||
* @var DateTimeZone
|
||||
*/
|
||||
private $timezone;
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $startOnSunday;
|
||||
|
||||
public function __construct(?DateTimeZone $timezone = null)
|
||||
public static function createByUser(User $user): self
|
||||
{
|
||||
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()), $user->isFirstDayOfWeekSunday());
|
||||
}
|
||||
|
||||
public function __construct(?DateTimeZone $timezone = null, bool $startOnSunday = false)
|
||||
{
|
||||
if (null === $timezone) {
|
||||
$timezone = new \DateTimeZone(date_default_timezone_get());
|
||||
}
|
||||
$this->setTimezone($timezone);
|
||||
$this->startOnSunday = $startOnSunday;
|
||||
}
|
||||
|
||||
public function setTimezone(DateTimeZone $timezone)
|
||||
protected function setTimezone(DateTimeZone $timezone)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
}
|
||||
@@ -51,7 +62,20 @@ class DateTimeFactory
|
||||
$date = $this->createDateTime('now');
|
||||
}
|
||||
|
||||
return $this->createWeekDateTime($date->format('o'), $date->format('W'), 1, 0, 0, 0);
|
||||
$from = clone $date;
|
||||
|
||||
$year = $from->format('o');
|
||||
$week = $from->format('W');
|
||||
$firstDay = 1;
|
||||
|
||||
if ($this->startOnSunday) {
|
||||
$from->modify('-1 week');
|
||||
$year = $from->format('o');
|
||||
$week = $from->format('W');
|
||||
$firstDay = 7;
|
||||
}
|
||||
|
||||
return $this->createWeekDateTime($year, $week, $firstDay, 0, 0, 0);
|
||||
}
|
||||
|
||||
public function getEndOfWeek(?DateTime $date = null): DateTime
|
||||
@@ -60,7 +84,9 @@ class DateTimeFactory
|
||||
$date = $this->createDateTime('now');
|
||||
}
|
||||
|
||||
return $this->createWeekDateTime($date->format('o'), $date->format('W'), 7, 23, 59, 59);
|
||||
$lastDay = $this->startOnSunday ? 6 : 7;
|
||||
|
||||
return $this->createWeekDateTime($date->format('o'), $date->format('W'), $lastDay, 23, 59, 59);
|
||||
}
|
||||
|
||||
public function getEndOfMonth(): DateTime
|
||||
|
||||
@@ -13,6 +13,7 @@ use App\Entity\Activity;
|
||||
use App\Entity\Project;
|
||||
use App\Entity\User;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Timesheet\DateTimeFactory;
|
||||
use DateTime;
|
||||
|
||||
class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
@@ -30,8 +31,8 @@ class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
$this->setId('DailyWorkingTimeChart');
|
||||
$this->setTitle('stats.yourWorkingHours');
|
||||
$this->setOptions([
|
||||
'begin' => 'monday this week 00:00:00',
|
||||
'end' => 'sunday this week 23:59:59',
|
||||
'begin' => null,
|
||||
'end' => null,
|
||||
'color' => '',
|
||||
'type' => self::DEFAULT_CHART,
|
||||
'id' => '',
|
||||
@@ -67,12 +68,22 @@ class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
throw new \InvalidArgumentException('Widget option "user" must be an instance of ' . User::class);
|
||||
}
|
||||
|
||||
$dateTimeFactory = DateTimeFactory::createByUser($user);
|
||||
|
||||
if ($options['begin'] === null) {
|
||||
$options['begin'] = $dateTimeFactory->getStartOfWeek();
|
||||
}
|
||||
|
||||
if ($options['begin'] instanceof DateTime) {
|
||||
$begin = $options['begin'];
|
||||
} else {
|
||||
$begin = new DateTime($options['begin'], new \DateTimeZone($user->getTimezone()));
|
||||
}
|
||||
|
||||
if ($options['end'] === null) {
|
||||
$options['end'] = $dateTimeFactory->getEndOfWeek($begin);
|
||||
}
|
||||
|
||||
if ($options['end'] instanceof DateTime) {
|
||||
$end = $options['end'];
|
||||
} else {
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace App\Widget\Type;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\TimesheetRepository;
|
||||
use App\Timesheet\DateTimeFactory;
|
||||
use DateTime;
|
||||
|
||||
final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
@@ -54,15 +55,6 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
return $options;
|
||||
}
|
||||
|
||||
private function getDate(\DateTimeZone $timezone, $year, $week, $day, $hour, $minute, $second)
|
||||
{
|
||||
$now = new DateTime('now', $timezone);
|
||||
$now->setISODate($year, $week, $day);
|
||||
$now->setTime($hour, $minute, $second);
|
||||
|
||||
return $now;
|
||||
}
|
||||
|
||||
private function getLastWeekInYear($year): int
|
||||
{
|
||||
$lastWeekInYear = new DateTime();
|
||||
@@ -80,17 +72,23 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
throw new \InvalidArgumentException('Widget option "user" must be an instance of ' . User::class);
|
||||
}
|
||||
|
||||
$timezone = new \DateTimeZone($user->getTimezone());
|
||||
$dateTimeFactory = DateTimeFactory::createByUser($user);
|
||||
|
||||
$weekBegin = $this->getDate($timezone, $options['year'], $options['week'], 1, 0, 0, 0);
|
||||
$weekEnd = $this->getDate($timezone, $options['year'], $options['week'], 7, 23, 59, 59);
|
||||
$year = $options['year'];
|
||||
$week = $options['week'];
|
||||
|
||||
$lastWeekInYear = $this->getLastWeekInYear($options['year']);
|
||||
$lastWeekInLastYear = $this->getLastWeekInYear($options['year'] - 1);
|
||||
$weekBegin = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
|
||||
$weekEnd = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 7)->setTime(23, 59, 59);
|
||||
|
||||
$weekBegin = $dateTimeFactory->getStartOfWeek($weekBegin);
|
||||
$weekEnd = $dateTimeFactory->getEndOfWeek($weekEnd);
|
||||
|
||||
$lastWeekInYear = $this->getLastWeekInYear($year);
|
||||
$lastWeekInLastYear = $this->getLastWeekInYear($year - 1);
|
||||
|
||||
$thisMonth = clone $weekBegin;
|
||||
if ((int) $options['week'] === 1) {
|
||||
$thisMonth = (new DateTime('now', $timezone))->setISODate($options['year'], $options['week'], 7)->setTime(0, 0, 0);
|
||||
if ((int) $week === 1) {
|
||||
$thisMonth = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -102,8 +100,8 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
'lastWeekInLastYear' => $lastWeekInLastYear,
|
||||
'day' => $this->repository->getStatistic(
|
||||
'duration',
|
||||
new DateTime('00:00:00', $timezone),
|
||||
new DateTime('23:59:59', $timezone),
|
||||
$dateTimeFactory->createDateTime('00:00:00'),
|
||||
$dateTimeFactory->createDateTime('23:59:59'),
|
||||
$user
|
||||
),
|
||||
'week' => $this->repository->getStatistic(
|
||||
@@ -114,14 +112,14 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
|
||||
),
|
||||
'month' => $this->repository->getStatistic(
|
||||
'duration',
|
||||
(clone $weekBegin)->setDate($weekBegin->format('Y'), $weekBegin->format('n'), 1)->setTime(0, 0, 0),
|
||||
(clone $weekBegin)->setDate($weekBegin->format('Y'), $weekBegin->format('n'), $weekBegin->format('t'))->setTime(23, 59, 59),
|
||||
(clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), 1)->setTime(0, 0, 0),
|
||||
(clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), (int) $weekBegin->format('t'))->setTime(23, 59, 59),
|
||||
$user
|
||||
),
|
||||
'year' => $this->repository->getStatistic(
|
||||
'duration',
|
||||
new DateTime(sprintf('01 january %s 00:00:00', $options['year']), $timezone),
|
||||
new DateTime(sprintf('31 december %s 23:59:59', $options['year']), $timezone),
|
||||
$dateTimeFactory->createDateTime(sprintf('01 january %s 00:00:00', $year)),
|
||||
$dateTimeFactory->createDateTime(sprintf('31 december %s 23:59:59', $year)),
|
||||
$user
|
||||
),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user