added project filter in user-list reports (#4615)
This commit is contained in:
40
phpstan.neon
40
phpstan.neon
@@ -1032,11 +1032,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Controller/Reporting/CustomerMonthlyProjectsController.php
|
path: src/Controller/Reporting/CustomerMonthlyProjectsController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$users of method App\\\\Reporting\\\\CustomerMonthlyProjects\\\\CustomerMonthlyProjectsRepository\\:\\:getGroupedByCustomerProjectActivityUser\\(\\) expects array\\<App\\\\Entity\\\\User\\>, iterable\\<App\\\\Entity\\\\User\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Controller/Reporting/CustomerMonthlyProjectsController.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
|
message: "#^Cannot call method getId\\(\\) on App\\\\Entity\\\\Customer\\|null\\.$#"
|
||||||
count: 3
|
count: 3
|
||||||
@@ -1052,31 +1047,16 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Controller/Reporting/ReportUsersMonthController.php
|
path: src/Controller/Reporting/ReportUsersMonthController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$users of method App\\\\Timesheet\\\\TimesheetStatisticService\\:\\:getDailyStatistics\\(\\) expects array\\<App\\\\Entity\\\\User\\>, iterable\\<App\\\\Entity\\\\User\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Controller/Reporting/ReportUsersMonthController.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method App\\\\Controller\\\\Reporting\\\\ReportUsersWeekController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
message: "#^Method App\\\\Controller\\\\Reporting\\\\ReportUsersWeekController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: src/Controller/Reporting/ReportUsersWeekController.php
|
path: src/Controller/Reporting/ReportUsersWeekController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$users of method App\\\\Timesheet\\\\TimesheetStatisticService\\:\\:getDailyStatistics\\(\\) expects array\\<App\\\\Entity\\\\User\\>, iterable\\<App\\\\Entity\\\\User\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Controller/Reporting/ReportUsersWeekController.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method App\\\\Controller\\\\Reporting\\\\ReportUsersYearController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
message: "#^Method App\\\\Controller\\\\Reporting\\\\ReportUsersYearController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: src/Controller/Reporting/ReportUsersYearController.php
|
path: src/Controller/Reporting/ReportUsersYearController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#3 \\$users of method App\\\\Timesheet\\\\TimesheetStatisticService\\:\\:getMonthlyStats\\(\\) expects array\\<App\\\\Entity\\\\User\\>, iterable\\<App\\\\Entity\\\\User\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Controller/Reporting/ReportUsersYearController.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Method App\\\\Controller\\\\Reporting\\\\UserMonthController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
message: "#^Method App\\\\Controller\\\\Reporting\\\\UserMonthController\\:\\:getData\\(\\) return type has no value type specified in iterable type array\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
@@ -1182,11 +1162,6 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Controller/TimesheetTeamController.php
|
path: src/Controller/TimesheetTeamController.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$entries of method App\\\\Export\\\\Spreadsheet\\\\UserExporter\\:\\:export\\(\\) expects array\\<App\\\\Entity\\\\User\\>, iterable\\<App\\\\Entity\\\\User\\> given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Controller/UserController.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#2 \\$plainPassword of method Symfony\\\\Component\\\\PasswordHasher\\\\Hasher\\\\UserPasswordHasherInterface\\:\\:hashPassword\\(\\) expects string, string\\|null given\\.$#"
|
message: "#^Parameter \\#2 \\$plainPassword of method Symfony\\\\Component\\\\PasswordHasher\\\\Hasher\\\\UserPasswordHasherInterface\\:\\:hashPassword\\(\\) expects string, string\\|null given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
@@ -4822,26 +4797,11 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Repository/UserRepository.php
|
path: src/Repository/UserRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method App\\\\Repository\\\\UserRepository\\:\\:getHydratedResultsByQuery\\(\\) should return iterable\\<App\\\\Entity\\\\User\\> but returns mixed\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Method App\\\\Repository\\\\UserRepository\\:\\:saveUser\\(\\) has no return type specified\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#1 \\$identifier of method App\\\\Repository\\\\UserRepository\\:\\:loadUserByIdentifier\\(\\) expects string, mixed given\\.$#"
|
message: "#^Parameter \\#1 \\$identifier of method App\\\\Repository\\\\UserRepository\\:\\:loadUserByIdentifier\\(\\) expects string, mixed given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
path: src/Repository/UserRepository.php
|
path: src/Repository/UserRepository.php
|
||||||
|
|
||||||
-
|
|
||||||
message: "#^Parameter \\#1 \\$results of method App\\\\Repository\\\\Loader\\\\UserLoader\\:\\:loadResults\\(\\) expects array\\<App\\\\Entity\\\\User\\|int\\>, mixed given\\.$#"
|
|
||||||
count: 1
|
|
||||||
path: src/Repository/UserRepository.php
|
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Parameter \\#1 \\$message of class Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AuthenticationException constructor expects string, string\\|null given\\.$#"
|
message: "#^Parameter \\#1 \\$message of class Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AuthenticationException constructor expects string, string\\|null given\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use App\Form\UserPreferencesForm;
|
|||||||
use App\Form\UserRolesType;
|
use App\Form\UserRolesType;
|
||||||
use App\Form\UserTeamsType;
|
use App\Form\UserTeamsType;
|
||||||
use App\Form\UserTwoFactorType;
|
use App\Form\UserTwoFactorType;
|
||||||
|
use App\Repository\Query\TimesheetStatisticQuery;
|
||||||
use App\Repository\TeamRepository;
|
use App\Repository\TeamRepository;
|
||||||
use App\Repository\TimesheetRepository;
|
use App\Repository\TimesheetRepository;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
@@ -84,13 +85,15 @@ final class ProfileController extends AbstractController
|
|||||||
// but we need a full year, because the chart needs always 12 month
|
// but we need a full year, because the chart needs always 12 month
|
||||||
$begin = $dateFactory->createStartOfYear($begin);
|
$begin = $dateFactory->createStartOfYear($begin);
|
||||||
|
|
||||||
|
$query = new TimesheetStatisticQuery($begin, $end, [$profile]);
|
||||||
|
|
||||||
$viewVars = [
|
$viewVars = [
|
||||||
'tab' => 'charts',
|
'tab' => 'charts',
|
||||||
'page_setup' => $this->getPageSetup($profile, 'charts'),
|
'page_setup' => $this->getPageSetup($profile, 'charts'),
|
||||||
'user' => $profile,
|
'user' => $profile,
|
||||||
'stats' => $userStats,
|
'stats' => $userStats,
|
||||||
'workingSince' => $workStartingDay,
|
'workingSince' => $workStartingDay,
|
||||||
'workMonths' => $statisticService->getMonthlyStats($begin, $end, [$profile])[0]
|
'workMonths' => $statisticService->getMonthlyStats($query)[0]
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this->render('user/stats.html.twig', $viewVars);
|
return $this->render('user/stats.html.twig', $viewVars);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use App\Export\Spreadsheet\Writer\XlsxWriter;
|
|||||||
use App\Model\DailyStatistic;
|
use App\Model\DailyStatistic;
|
||||||
use App\Reporting\MonthlyUserList\MonthlyUserList;
|
use App\Reporting\MonthlyUserList\MonthlyUserList;
|
||||||
use App\Reporting\MonthlyUserList\MonthlyUserListForm;
|
use App\Reporting\MonthlyUserList\MonthlyUserListForm;
|
||||||
|
use App\Repository\Query\TimesheetStatisticQuery;
|
||||||
use App\Repository\Query\UserQuery;
|
use App\Repository\Query\UserQuery;
|
||||||
use App\Repository\Query\VisibilityInterface;
|
use App\Repository\Query\VisibilityInterface;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
@@ -106,7 +107,9 @@ final class ReportUsersMonthController extends AbstractController
|
|||||||
$hasData = true;
|
$hasData = true;
|
||||||
|
|
||||||
if (!empty($allUsers)) {
|
if (!empty($allUsers)) {
|
||||||
$dayStats = $statisticService->getDailyStatistics($start, $end, $allUsers);
|
$statsQuery = new TimesheetStatisticQuery($start, $end, $allUsers);
|
||||||
|
$statsQuery->setProject($values->getProject());
|
||||||
|
$dayStats = $statisticService->getDailyStatistics($statsQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($dayStats)) {
|
if (empty($dayStats)) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use App\Export\Spreadsheet\Writer\XlsxWriter;
|
|||||||
use App\Model\DailyStatistic;
|
use App\Model\DailyStatistic;
|
||||||
use App\Reporting\WeeklyUserList\WeeklyUserList;
|
use App\Reporting\WeeklyUserList\WeeklyUserList;
|
||||||
use App\Reporting\WeeklyUserList\WeeklyUserListForm;
|
use App\Reporting\WeeklyUserList\WeeklyUserListForm;
|
||||||
|
use App\Repository\Query\TimesheetStatisticQuery;
|
||||||
use App\Repository\Query\UserQuery;
|
use App\Repository\Query\UserQuery;
|
||||||
use App\Repository\Query\VisibilityInterface;
|
use App\Repository\Query\VisibilityInterface;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
@@ -102,7 +103,9 @@ final class ReportUsersWeekController extends AbstractController
|
|||||||
$hasData = true;
|
$hasData = true;
|
||||||
|
|
||||||
if (!empty($allUsers)) {
|
if (!empty($allUsers)) {
|
||||||
$dayStats = $statisticService->getDailyStatistics($start, $end, $allUsers);
|
$statsQuery = new TimesheetStatisticQuery($start, $end, $allUsers);
|
||||||
|
$statsQuery->setProject($values->getProject());
|
||||||
|
$dayStats = $statisticService->getDailyStatistics($statsQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($dayStats)) {
|
if (empty($dayStats)) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use App\Export\Spreadsheet\Writer\XlsxWriter;
|
|||||||
use App\Model\MonthlyStatistic;
|
use App\Model\MonthlyStatistic;
|
||||||
use App\Reporting\YearlyUserList\YearlyUserList;
|
use App\Reporting\YearlyUserList\YearlyUserList;
|
||||||
use App\Reporting\YearlyUserList\YearlyUserListForm;
|
use App\Reporting\YearlyUserList\YearlyUserListForm;
|
||||||
|
use App\Repository\Query\TimesheetStatisticQuery;
|
||||||
use App\Repository\Query\UserQuery;
|
use App\Repository\Query\UserQuery;
|
||||||
use App\Repository\Query\VisibilityInterface;
|
use App\Repository\Query\VisibilityInterface;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
@@ -107,7 +108,9 @@ final class ReportUsersYearController extends AbstractController
|
|||||||
$hasData = true;
|
$hasData = true;
|
||||||
|
|
||||||
if (!empty($allUsers)) {
|
if (!empty($allUsers)) {
|
||||||
$monthStats = $statisticService->getMonthlyStats($start, $end, $allUsers);
|
$statsQuery = new TimesheetStatisticQuery($start, $end, $allUsers);
|
||||||
|
$statsQuery->setProject($values->getProject());
|
||||||
|
$monthStats = $statisticService->getMonthlyStats($statsQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($monthStats)) {
|
if (empty($monthStats)) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace App\Reporting;
|
namespace App\Reporting;
|
||||||
|
|
||||||
|
use App\Entity\Project;
|
||||||
use App\Entity\Team;
|
use App\Entity\Team;
|
||||||
|
|
||||||
abstract class AbstractUserList
|
abstract class AbstractUserList
|
||||||
@@ -17,6 +18,7 @@ abstract class AbstractUserList
|
|||||||
private bool $decimal = false;
|
private bool $decimal = false;
|
||||||
private string $sumType = 'duration';
|
private string $sumType = 'duration';
|
||||||
private ?Team $team = null;
|
private ?Team $team = null;
|
||||||
|
private ?Project $project = null;
|
||||||
|
|
||||||
public function getDate(): ?\DateTimeInterface
|
public function getDate(): ?\DateTimeInterface
|
||||||
{
|
{
|
||||||
@@ -61,4 +63,14 @@ abstract class AbstractUserList
|
|||||||
{
|
{
|
||||||
$this->team = $team;
|
$this->team = $team;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProject(): ?Project
|
||||||
|
{
|
||||||
|
return $this->project;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setProject(?Project $project): void
|
||||||
|
{
|
||||||
|
$this->project = $project;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace App\Reporting\MonthlyUserList;
|
namespace App\Reporting\MonthlyUserList;
|
||||||
|
|
||||||
use App\Form\Type\MonthPickerType;
|
use App\Form\Type\MonthPickerType;
|
||||||
|
use App\Form\Type\ProjectType;
|
||||||
use App\Form\Type\ReportSumType;
|
use App\Form\Type\ReportSumType;
|
||||||
use App\Form\Type\TeamType;
|
use App\Form\Type\TeamType;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
@@ -33,6 +34,11 @@ final class MonthlyUserListForm extends AbstractType
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'width' => false,
|
'width' => false,
|
||||||
]);
|
]);
|
||||||
|
$builder->add('project', ProjectType::class, [
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'width' => false,
|
||||||
|
]);
|
||||||
$builder->add('sumType', ReportSumType::class);
|
$builder->add('sumType', ReportSumType::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace App\Reporting\WeeklyUserList;
|
namespace App\Reporting\WeeklyUserList;
|
||||||
|
|
||||||
|
use App\Form\Type\ProjectType;
|
||||||
use App\Form\Type\ReportSumType;
|
use App\Form\Type\ReportSumType;
|
||||||
use App\Form\Type\TeamType;
|
use App\Form\Type\TeamType;
|
||||||
use App\Form\Type\WeekPickerType;
|
use App\Form\Type\WeekPickerType;
|
||||||
@@ -33,6 +34,11 @@ final class WeeklyUserListForm extends AbstractType
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'width' => false,
|
'width' => false,
|
||||||
]);
|
]);
|
||||||
|
$builder->add('project', ProjectType::class, [
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'width' => false,
|
||||||
|
]);
|
||||||
$builder->add('sumType', ReportSumType::class);
|
$builder->add('sumType', ReportSumType::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace App\Reporting\YearlyUserList;
|
namespace App\Reporting\YearlyUserList;
|
||||||
|
|
||||||
|
use App\Form\Type\ProjectType;
|
||||||
use App\Form\Type\ReportSumType;
|
use App\Form\Type\ReportSumType;
|
||||||
use App\Form\Type\TeamType;
|
use App\Form\Type\TeamType;
|
||||||
use App\Form\Type\YearPickerType;
|
use App\Form\Type\YearPickerType;
|
||||||
@@ -34,6 +35,11 @@ final class YearlyUserListForm extends AbstractType
|
|||||||
'required' => false,
|
'required' => false,
|
||||||
'width' => false,
|
'width' => false,
|
||||||
]);
|
]);
|
||||||
|
$builder->add('project', ProjectType::class, [
|
||||||
|
'multiple' => false,
|
||||||
|
'required' => false,
|
||||||
|
'width' => false,
|
||||||
|
]);
|
||||||
$builder->add('sumType', ReportSumType::class);
|
$builder->add('sumType', ReportSumType::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
57
src/Repository/Query/TimesheetStatisticQuery.php
Normal file
57
src/Repository/Query/TimesheetStatisticQuery.php
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<?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\Repository\Query;
|
||||||
|
|
||||||
|
use App\Entity\Project;
|
||||||
|
use App\Entity\User;
|
||||||
|
|
||||||
|
final class TimesheetStatisticQuery
|
||||||
|
{
|
||||||
|
private ?Project $project = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<User> $users
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
private readonly \DateTimeInterface $begin,
|
||||||
|
private readonly \DateTimeInterface $end,
|
||||||
|
private array $users
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBegin(): \DateTimeInterface
|
||||||
|
{
|
||||||
|
return $this->begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEnd(): \DateTimeInterface
|
||||||
|
{
|
||||||
|
return $this->end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return User[]
|
||||||
|
*/
|
||||||
|
public function getUsers(): array
|
||||||
|
{
|
||||||
|
return $this->users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProject(): ?Project
|
||||||
|
{
|
||||||
|
return $this->project;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setProject(?Project $project): void
|
||||||
|
{
|
||||||
|
$this->project = $project;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ class UserRepository extends EntityRepository implements UserLoaderInterface, Us
|
|||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
* @throws \Doctrine\ORM\OptimisticLockException
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
*/
|
*/
|
||||||
public function saveUser(User $user)
|
public function saveUser(User $user): void
|
||||||
{
|
{
|
||||||
$entityManager = $this->getEntityManager();
|
$entityManager = $this->getEntityManager();
|
||||||
$entityManager->persist($user);
|
$entityManager->persist($user);
|
||||||
@@ -397,7 +397,7 @@ class UserRepository extends EntityRepository implements UserLoaderInterface, Us
|
|||||||
* @param UserQuery $query
|
* @param UserQuery $query
|
||||||
* @return User[]
|
* @return User[]
|
||||||
*/
|
*/
|
||||||
public function getUsersForQuery(UserQuery $query): iterable
|
public function getUsersForQuery(UserQuery $query): array
|
||||||
{
|
{
|
||||||
$qb = $this->getQueryBuilderForQuery($query);
|
$qb = $this->getQueryBuilderForQuery($query);
|
||||||
|
|
||||||
@@ -408,8 +408,9 @@ class UserRepository extends EntityRepository implements UserLoaderInterface, Us
|
|||||||
* @param QueryBuilder $qb
|
* @param QueryBuilder $qb
|
||||||
* @return User[]
|
* @return User[]
|
||||||
*/
|
*/
|
||||||
protected function getHydratedResultsByQuery(QueryBuilder $qb): iterable
|
protected function getHydratedResultsByQuery(QueryBuilder $qb): array
|
||||||
{
|
{
|
||||||
|
/** @var array<User> $results */
|
||||||
$results = $qb->getQuery()->getResult();
|
$results = $qb->getQuery()->getResult();
|
||||||
|
|
||||||
$loader = new UserLoader($qb->getEntityManager());
|
$loader = new UserLoader($qb->getEntityManager());
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ namespace App\Timesheet;
|
|||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Model\DailyStatistic;
|
use App\Model\DailyStatistic;
|
||||||
use App\Model\MonthlyStatistic;
|
use App\Model\MonthlyStatistic;
|
||||||
|
use App\Repository\Query\TimesheetStatisticQuery;
|
||||||
use App\Repository\TimesheetRepository;
|
use App\Repository\TimesheetRepository;
|
||||||
use DateTime;
|
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
|
||||||
final class TimesheetStatisticService
|
final class TimesheetStatisticService
|
||||||
@@ -23,13 +23,15 @@ final class TimesheetStatisticService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param DateTimeInterface $begin
|
|
||||||
* @param DateTimeInterface $end
|
|
||||||
* @param User[] $users
|
|
||||||
* @return DailyStatistic[]
|
* @return DailyStatistic[]
|
||||||
*/
|
*/
|
||||||
public function getDailyStatistics(DateTimeInterface $begin, DateTimeInterface $end, array $users): array
|
public function getDailyStatistics(TimesheetStatisticQuery $query): array
|
||||||
{
|
{
|
||||||
|
$begin = $query->getBegin();
|
||||||
|
$end = $query->getEnd();
|
||||||
|
$users = $query->getUsers();
|
||||||
|
$project = $query->getProject();
|
||||||
|
|
||||||
/** @var DailyStatistic[] $stats */
|
/** @var DailyStatistic[] $stats */
|
||||||
$stats = [];
|
$stats = [];
|
||||||
|
|
||||||
@@ -63,6 +65,13 @@ final class TimesheetStatisticService
|
|||||||
->addGroupBy('billable')
|
->addGroupBy('billable')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if ($project !== null) {
|
||||||
|
$qb
|
||||||
|
->andWhere($qb->expr()->eq('t.project', ':project'))
|
||||||
|
->setParameter('project', $project)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
$results = $qb->getQuery()->getResult();
|
$results = $qb->getQuery()->getResult();
|
||||||
|
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
@@ -241,7 +250,7 @@ final class TimesheetStatisticService
|
|||||||
return $stats;
|
return $stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findFirstRecordDate(User $user): ?DateTime
|
public function findFirstRecordDate(User $user): ?\DateTimeImmutable
|
||||||
{
|
{
|
||||||
$result = $this->repository->createQueryBuilder('t')
|
$result = $this->repository->createQueryBuilder('t')
|
||||||
->select('MIN(t.begin)')
|
->select('MIN(t.begin)')
|
||||||
@@ -254,19 +263,19 @@ final class TimesheetStatisticService
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DateTime((string) $result, new \DateTimeZone($user->getTimezone()));
|
return new \DateTimeImmutable((string) $result, new \DateTimeZone($user->getTimezone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of Year statistics.
|
|
||||||
*
|
|
||||||
* @param DateTime $begin
|
|
||||||
* @param DateTime $end
|
|
||||||
* @param User[] $users
|
|
||||||
* @return MonthlyStatistic[]
|
* @return MonthlyStatistic[]
|
||||||
*/
|
*/
|
||||||
public function getMonthlyStats(DateTime $begin, DateTime $end, array $users): array
|
public function getMonthlyStats(TimesheetStatisticQuery $query): array
|
||||||
{
|
{
|
||||||
|
$begin = $query->getBegin();
|
||||||
|
$end = $query->getEnd();
|
||||||
|
$users = $query->getUsers();
|
||||||
|
$project = $query->getProject();
|
||||||
|
|
||||||
/** @var MonthlyStatistic[] $stats */
|
/** @var MonthlyStatistic[] $stats */
|
||||||
$stats = [];
|
$stats = [];
|
||||||
|
|
||||||
@@ -297,6 +306,13 @@ final class TimesheetStatisticService
|
|||||||
->addGroupBy('billable')
|
->addGroupBy('billable')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
if ($project !== null) {
|
||||||
|
$qb
|
||||||
|
->andWhere($qb->expr()->eq('t.project', ':project'))
|
||||||
|
->setParameter('project', $project)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
$results = $qb->getQuery()->getResult();
|
$results = $qb->getQuery()->getResult();
|
||||||
|
|
||||||
foreach ($results as $row) {
|
foreach ($results as $row) {
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
{% if form.team is defined %}
|
{% if form.team is defined %}
|
||||||
{{ form_widget(form.team, {'label': false, 'placeholder': 'please_choose'}) }}
|
{{ form_widget(form.team, {'label': false, 'placeholder': 'please_choose'}) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if form.project is defined %}
|
||||||
|
{{ form_widget(form.project, {'label': false, 'placeholder': 'please_choose'}) }}
|
||||||
|
{% endif %}
|
||||||
{{ form_widget(form.sumType) }}
|
{{ form_widget(form.sumType) }}
|
||||||
{% from '@theme/components/buttons.html.twig' import submit_button %}
|
{% from '@theme/components/buttons.html.twig' import submit_button %}
|
||||||
{{ submit_button('download', {'attr': {'formaction': path(export_route)}, 'icon': 'download', 'combined': false}, 'primary') }}
|
{{ submit_button('download', {'attr': {'formaction': path(export_route)}, 'icon': 'download', 'combined': false}, 'primary') }}
|
||||||
|
|||||||
Reference in New Issue
Block a user