monthly budget, monthly report, unified report calculation (#2684)

This commit is contained in:
Kevin Papst
2021-08-06 18:38:41 +02:00
committed by GitHub
parent 21f785638c
commit cefd747e91
196 changed files with 5031 additions and 2167 deletions

View File

@@ -124,6 +124,7 @@ final class ActivityController extends AbstractController
$rates = [];
$teams = null;
$defaultTeam = null;
$now = $this->getDateTimeFactory()->createDateTime();
if ($this->isGranted('edit', $activity)) {
if ($this->isGranted('create_team')) {
@@ -133,7 +134,7 @@ final class ActivityController extends AbstractController
}
if ($this->isGranted('budget', $activity)) {
$stats = $statisticService->getActivityStatistics($activity);
$stats = $statisticService->getBudgetStatisticModel($activity, $now);
}
if ($this->isGranted('permissions', $activity) || $this->isGranted('details', $activity) || $this->isGranted('view_team')) {
@@ -146,7 +147,7 @@ final class ActivityController extends AbstractController
'rates' => $rates,
'team' => $defaultTeam,
'teams' => $teams,
'now' => $this->getDateTimeFactory()->createDateTime(),
'now' => $now,
]);
}

View File

@@ -283,6 +283,7 @@ final class CustomerController extends AbstractController
$teams = null;
$projects = null;
$rates = [];
$now = $this->getDateTimeFactory()->createDateTime();
if ($this->isGranted('edit', $customer)) {
if ($this->isGranted('create_team')) {
@@ -296,7 +297,7 @@ final class CustomerController extends AbstractController
}
if ($this->isGranted('budget', $customer)) {
$stats = $statisticService->getCustomerStatistics($customer);
$stats = $statisticService->getBudgetStatisticModel($customer, $now);
}
if ($this->isGranted('comments', $customer)) {
@@ -321,7 +322,7 @@ final class CustomerController extends AbstractController
'teams' => $teams,
'customer_now' => new \DateTime('now', $timezone),
'rates' => $rates,
'now' => $this->getDateTimeFactory()->createDateTime(),
'now' => $now,
]);
}

View File

@@ -19,8 +19,8 @@ use App\Form\UserPreferencesForm;
use App\Form\UserRolesType;
use App\Form\UserTeamsType;
use App\Repository\TimesheetRepository;
use App\Timesheet\TimesheetStatisticService;
use App\User\UserService;
use App\Utils\LocaleSettings;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormInterface;
@@ -48,20 +48,20 @@ final class ProfileController extends AbstractController
* @Route(path="/{username}", name="user_profile", methods={"GET"})
* @Security("is_granted('view', profile)")
*/
public function indexAction(User $profile, TimesheetRepository $repository, LocaleSettings $localeSettings): Response
public function indexAction(User $profile, TimesheetRepository $repository, TimesheetStatisticService $statisticService): Response
{
$userStats = $repository->getUserStatistics($profile);
$userStats = $repository->getUserStatistics($profile, false);
$firstEntry = $statisticService->findFirstRecordDate($profile);
$begin = $userStats->getFirstEntry() ?? $this->getDateTimeFactory()->getStartOfMonth();
$begin = $firstEntry ?? $this->getDateTimeFactory()->getStartOfMonth();
$end = $this->getDateTimeFactory()->getEndOfMonth();
$monthlyStats = $repository->getMonthlyStats($begin, $end, $profile);
arsort($monthlyStats);
$viewVars = [
'tab' => 'charts',
'user' => $profile,
'stats' => $userStats,
'years' => $monthlyStats,
'firstTimesheet' => $firstEntry,
'workMonths' => $statisticService->getMonthlyStats($begin, $end, [$profile])[0]
];
return $this->render('user/stats.html.twig', $viewVars);

View File

@@ -304,6 +304,7 @@ final class ProjectController extends AbstractController
$comments = null;
$teams = null;
$rates = [];
$now = $this->getDateTimeFactory()->createDateTime();
if ($this->isGranted('edit', $project)) {
if ($this->isGranted('create_team')) {
@@ -313,7 +314,7 @@ final class ProjectController extends AbstractController
}
if ($this->isGranted('budget', $project)) {
$stats = $statisticService->getProjectStatistics($project);
$stats = $statisticService->getBudgetStatisticModel($project, $now);
}
if ($this->isGranted('comments', $project)) {
@@ -337,7 +338,7 @@ final class ProjectController extends AbstractController
'team' => $defaultTeam,
'teams' => $teams,
'rates' => $rates,
'now' => $this->getDateTimeFactory()->createDateTime(),
'now' => $now,
]);
}

View File

@@ -0,0 +1,60 @@
<?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\Controller\Reporting;
use App\Controller\AbstractController;
use App\Form\Model\DateRange;
use App\Project\ProjectStatisticService;
use App\Reporting\ProjectDateRange\ProjectDateRangeForm;
use App\Reporting\ProjectDateRange\ProjectDateRangeQuery;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
final class ProjectDateRangeController extends AbstractController
{
/**
* @Route(path="/reporting/project_daterange", name="report_project_daterange", methods={"GET","POST"})
* @Security("is_granted('view_reporting') and is_granted('budget_project')")
*/
public function __invoke(Request $request, ProjectStatisticService $service)
{
$dateFactory = $this->getDateTimeFactory();
$user = $this->getUser();
$query = new ProjectDaterangeQuery($dateFactory->getStartOfMonth(), $user);
$form = $this->createForm(ProjectDateRangeForm::class, $query, [
'timezone' => $user->getTimezone()
]);
$form->submit($request->query->all(), false);
$dateRange = new DateRange(true);
$dateRange->setBegin($query->getMonth());
$dateRange->setEnd($dateFactory->getEndOfMonth($dateRange->getBegin()));
$projects = $service->findProjectsForDateRange($query, $dateRange);
$entries = $service->getBudgetStatisticModelForProjectsByDateRange($projects, $dateRange->getBegin(), $dateRange->getEnd(), $dateRange->getEnd());
$byCustomer = [];
foreach ($entries as $entry) {
$customer = $entry->getProject()->getCustomer();
if (!isset($byCustomer[$customer->getId()])) {
$byCustomer[$customer->getId()] = ['customer' => $customer, 'projects' => []];
}
$byCustomer[$customer->getId()]['projects'][] = $entry;
}
return $this->render('reporting/project_daterange.html.twig', [
'entries' => $byCustomer,
'form' => $form->createView(),
'queryEnd' => $dateRange->getEnd(),
]);
}
}

View File

@@ -43,6 +43,7 @@ final class ProjectDetailsController extends AbstractController
}
return $this->render('reporting/project_details.html.twig', [
'project' => $query->getProject(),
'project_view' => $projectView,
'project_details' => $projectDetails,
'form' => $form->createView(),

View File

@@ -17,7 +17,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
final class InactiveProjectController extends AbstractController
final class ProjectInactiveController extends AbstractController
{
/**
* @Route(path="/reporting/project_inactive", name="report_project_inactive", methods={"GET","POST"})
@@ -27,6 +27,7 @@ final class InactiveProjectController extends AbstractController
{
$dateFactory = $this->getDateTimeFactory();
$user = $this->getUser();
$now = $dateFactory->createDateTime();
$query = new ProjectInactiveQuery($dateFactory->createDateTime('-1 year'), $user);
$form = $this->createForm(ProjectInactiveForm::class, $query, [
@@ -35,7 +36,7 @@ final class InactiveProjectController extends AbstractController
$form->submit($request->query->all(), false);
$projects = $service->findInactiveProjects($query);
$entries = $service->getProjectView($user, $projects, $query->getLastChange());
$entries = $service->getProjectView($user, $projects, $now);
$byCustomer = [];
foreach ($entries as $entry) {
@@ -51,7 +52,8 @@ final class InactiveProjectController extends AbstractController
'form' => $form->createView(),
'title' => 'report_inactive_project',
'tableName' => 'inactive_project_reporting',
'now' => $this->getDateTimeFactory()->createDateTime(),
'now' => $now,
'skipColumns' => ['today', 'week', 'month', 'projectStart', 'projectEnd', 'comment'],
]);
}
}

View File

@@ -49,8 +49,7 @@ final class ProjectViewController extends AbstractController
'form' => $form->createView(),
'title' => 'report_project_view',
'tableName' => 'project_view_reporting',
'now' => $this->getDateTimeFactory()->createDateTime(),
'showDurations' => true,
'now' => $dateFactory->createDateTime(),
]);
}
}

View File

@@ -10,12 +10,18 @@
namespace App\Controller\Reporting;
use App\Controller\AbstractController;
use App\Model\Statistic\Day;
use App\Entity\User;
use App\Model\DailyStatistic;
use App\Model\Statistic\StatisticDate;
use App\Reporting\MonthByUser;
use App\Reporting\MonthByUserForm;
use App\Reporting\WeekByUser;
use App\Reporting\WeekByUserForm;
use App\Repository\ActivityRepository;
use App\Repository\ProjectRepository;
use App\Repository\TimesheetRepository;
use App\Timesheet\TimesheetStatisticService;
use DateTime;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
@@ -29,14 +35,17 @@ use Symfony\Component\Security\Core\Exception\AccessDeniedException;
*/
final class ReportByUserController extends AbstractController
{
/**
* @var TimesheetRepository
*/
private $timesheetRepository;
private $statisticService;
private $projectRepository;
private $activityRepository;
public function __construct(TimesheetRepository $timesheetRepository)
public function __construct(TimesheetRepository $timesheetRepository, TimesheetStatisticService $statisticService, ProjectRepository $projectRepository, ActivityRepository $activityRepository)
{
$this->timesheetRepository = $timesheetRepository;
$this->statisticService = $statisticService;
$this->projectRepository = $projectRepository;
$this->activityRepository = $activityRepository;
}
private function canSelectUser(): bool
@@ -60,7 +69,6 @@ final class ReportByUserController extends AbstractController
{
$currentUser = $this->getUser();
$dateTimeFactory = $this->getDateTimeFactory($currentUser);
$localeFormats = $this->getLocaleFormats($request->getLocale());
$canChangeUser = $this->canSelectUser();
$values = new MonthByUser();
@@ -71,7 +79,6 @@ final class ReportByUserController extends AbstractController
'include_user' => $canChangeUser,
'timezone' => $dateTimeFactory->getTimezone()->getName(),
'start_date' => $values->getDate(),
'format' => $localeFormats->getDateTypeFormat(),
]);
$form->submit($request->query->all(), false);
@@ -102,15 +109,14 @@ final class ReportByUserController extends AbstractController
$nextMonth = clone $start;
$nextMonth->modify('+1 month');
$data = $this->timesheetRepository->getDailyStats($selectedUser, $start, $end);
$rows = $this->prepareReportData($data);
$data = $this->prepareReport($start, $end, $selectedUser);
return $this->render('reporting/report_by_user.html.twig', [
'report_title' => 'report_user_month',
'box_id' => 'user-month-reporting-box',
'form' => $form->createView(),
'days' => $data,
'rows' => $rows,
'rows' => $data,
'days' => new DailyStatistic($start, $end, $selectedUser),
'user' => $selectedUser,
'current' => $start,
'next' => $nextMonth,
@@ -129,7 +135,6 @@ final class ReportByUserController extends AbstractController
{
$currentUser = $this->getUser();
$dateTimeFactory = $this->getDateTimeFactory($currentUser);
$localeFormats = $this->getLocaleFormats($request->getLocale());
$canChangeUser = $this->canSelectUser();
$values = new WeekByUser();
@@ -140,7 +145,6 @@ final class ReportByUserController extends AbstractController
'include_user' => $canChangeUser,
'timezone' => $dateTimeFactory->getTimezone()->getName(),
'start_date' => $values->getDate(),
'format' => $localeFormats->getDateTypeFormat(),
]);
$form->submit($request->query->all(), false);
@@ -159,7 +163,6 @@ final class ReportByUserController extends AbstractController
$start = $dateTimeFactory->getStartOfWeek($values->getDate());
$end = $dateTimeFactory->getEndOfWeek($values->getDate());
$selectedUser = $values->getUser();
$previous = clone $start;
@@ -168,15 +171,14 @@ final class ReportByUserController extends AbstractController
$next = clone $start;
$next->modify('+1 week');
$data = $this->timesheetRepository->getDailyStats($selectedUser, $start, $end);
$rows = $this->prepareReportData($data);
$data = $this->prepareReport($start, $end, $selectedUser);
return $this->render('reporting/report_by_user.html.twig', [
'report_title' => 'report_user_week',
'box_id' => 'user-week-reporting-box',
'form' => $form->createView(),
'days' => $data,
'rows' => $rows,
'days' => new DailyStatistic($start, $end, $selectedUser),
'rows' => $data,
'user' => $selectedUser,
'current' => $start,
'next' => $next,
@@ -184,50 +186,52 @@ final class ReportByUserController extends AbstractController
]);
}
/**
* @param Day[] $data
* @return array
*/
private function prepareReportData(array $data): array
private function prepareReport(DateTime $begin, DateTime $end, User $user): array
{
$days = [];
$data = $this->statisticService->getDailyStatisticsGrouped($begin, $end, [$user]);
foreach ($data as $day) {
$days[$day->getDay()->format('Ymd')] = ['date' => $day->getDay(), 'duration' => 0];
$data = array_pop($data);
$projectIds = [];
$activityIds = [];
foreach ($data as $projectId => $projectValues) {
$projectIds[$projectId] = $projectId;
$dailyProjectStatistic = new DailyStatistic($begin, $end, $user);
foreach ($projectValues['activities'] as $activityId => $activityValues) {
$activityIds[$activityId] = $activityId;
if (!isset($data[$projectId]['duration'])) {
$data[$projectId]['duration'] = 0;
}
if (!isset($data[$projectId]['activities'][$activityId]['duration'])) {
$data[$projectId]['activities'][$activityId]['duration'] = 0;
}
/** @var StatisticDate $day */
foreach ($activityValues['days']->getDays() as $day) {
$statDay = $dailyProjectStatistic->getDayByDateTime($day->getDate());
$statDay->setTotalDuration($statDay->getTotalDuration() + $day->getDuration());
$data[$projectId]['duration'] = $data[$projectId]['duration'] + $day->getDuration();
$data[$projectId]['activities'][$activityId]['duration'] = $data[$projectId]['activities'][$activityId]['duration'] + $day->getDuration();
}
}
$data[$projectId]['days'] = $dailyProjectStatistic;
}
$rows = [];
$activities = $this->activityRepository->findByIds($activityIds);
foreach ($activities as $activity) {
$activityIds[$activity->getId()] = $activity;
}
foreach ($data as $day) {
$dayId = $day->getDay()->format('Ymd');
foreach ($day->getDetails() as $id => $detail) {
$projectId = $detail['project']->getId();
if (!\array_key_exists($projectId, $rows)) {
$rows[$projectId] = [
'project' => $detail['project'],
'duration' => 0,
'days' => $days,
'activities' => [],
];
}
$rows[$projectId]['duration'] += $detail['duration'];
$rows[$projectId]['days'][$dayId]['duration'] += $detail['duration'];
$activityId = $detail['activity']->getId();
if (!\array_key_exists($activityId, $rows[$projectId]['activities'])) {
$rows[$projectId]['activities'][$activityId] = [
'activity' => $detail['activity'],
'duration' => 0,
'days' => $days,
];
}
$rows[$projectId]['activities'][$activityId]['duration'] += $detail['duration'];
$rows[$projectId]['activities'][$activityId]['days'][$dayId]['duration'] += $detail['duration'];
foreach ($data as $projectId => $projectValues) {
foreach ($projectValues['activities'] as $activityId => $activityValues) {
$data[$projectId]['activities'][$activityId]['activity'] = $activityIds[$activityId];
}
}
return $rows;
$projects = $this->projectRepository->findByIds($projectIds);
foreach ($projects as $project) {
$data[$project->getId()]['project'] = $project;
}
return $data;
}
}

View File

@@ -11,8 +11,8 @@ namespace App\Controller\Reporting;
use App\Configuration\SystemConfiguration;
use App\Controller\AbstractController;
use App\Model\Statistic\Day;
use App\Model\Statistic\Year;
use App\Model\DailyStatistic;
use App\Model\MonthlyStatistic;
use App\Reporting\MonthlyUserList;
use App\Reporting\MonthlyUserListForm;
use App\Reporting\WeeklyUserList;
@@ -22,6 +22,7 @@ use App\Reporting\YearlyUserListForm;
use App\Repository\Query\UserQuery;
use App\Repository\TimesheetRepository;
use App\Repository\UserRepository;
use App\Timesheet\TimesheetStatisticService;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
@@ -34,13 +35,7 @@ use Symfony\Component\Routing\Annotation\Route;
*/
final class ReportUsersListController extends AbstractController
{
/**
* @var TimesheetRepository
*/
private $timesheetRepository;
/**
* @var UserRepository
*/
private $userRepository;
public function __construct(TimesheetRepository $timesheetRepository, UserRepository $userRepository)
@@ -56,11 +51,10 @@ final class ReportUsersListController extends AbstractController
* @return Response
* @throws Exception
*/
public function yearlyUsersList(Request $request, SystemConfiguration $systemConfiguration): Response
public function yearlyUsersList(Request $request, SystemConfiguration $systemConfiguration, TimesheetStatisticService $statisticService): Response
{
$currentUser = $this->getUser();
$dateTimeFactory = $this->getDateTimeFactory();
$localeFormats = $this->getLocaleFormats($request->getLocale());
$query = new UserQuery();
$query->setCurrentUser($currentUser);
@@ -71,15 +65,12 @@ final class ReportUsersListController extends AbstractController
$defaultDate = $this->getDateTimeFactory()->createStartOfFinancialYear($financialYear);
}
$rows = [];
$values = new YearlyUserList();
$values->setDate(clone $defaultDate);
$form = $this->createForm(YearlyUserListForm::class, $values, [
'timezone' => $dateTimeFactory->getTimezone()->getName(),
'start_date' => $values->getDate(),
'format' => $localeFormats->getDateTypeFormat(),
]);
$form->submit($request->query->all(), false);
@@ -93,123 +84,49 @@ final class ReportUsersListController extends AbstractController
}
$start = $values->getDate();
$end = $this->getDateTimeFactory()->createEndOfFinancialYear($start);
// there is a potential edge case bug for financial years:
// the last month will be skipped, if the financial year started on a different day than the first
$end = $dateTimeFactory->createEndOfFinancialYear($start);
$months = [];
$totals = [];
foreach ($allUsers as $user) {
$rows[] = [
'years' => $this->timesheetRepository->getMonthlyStats($start, $end, $user),
'user' => $user
];
$monthStats = [];
$hasData = true;
if (!empty($allUsers)) {
$monthStats = $statisticService->getMonthlyStats($start, $end, $allUsers);
}
if (isset($rows[0])) {
/** @var Year $year */
foreach ($rows[0]['years'] as $year) {
foreach ($year->getMonths() as $month) {
$date = new \DateTime();
$date->setDate((int) $year->getYear(), $month->getMonthNumber(), 1);
$date->setTime(0, 0, 0);
$months[$date->format('Ym')] = $date;
}
}
foreach ($rows as $row) {
foreach ($row['years'] as $year) {
foreach ($year->getMonths() as $month) {
$date = new \DateTime();
$date->setDate((int) $year->getYear(), $month->getMonthNumber(), 1);
$totalsId = $date->format('Ym');
if (!isset($totals[$totalsId])) {
$totals[$totalsId] = 0;
}
$totals[$totalsId] += $month->getTotalDuration();
}
}
}
if (empty($monthStats)) {
$monthStats = [new MonthlyStatistic($start, $end, $currentUser)];
$hasData = false;
}
/*
foreach ($allUsers as $user) {
$rows[] = [
'days' => $this->timesheetRepository->getDailyStats($user, $start, $end),
'user' => $user
];
}
$userYears = [];
if (isset($rows[0])) {
foreach ($rows[0]['days'] as $day) {
$months[$day->getDay()->format('Ym')] = $day->getDay();
}
foreach ($rows as $row) {
$userYear = ['user' => $row['user']];
foreach ($row['days'] as $day) {
$yearId = $day->getDay()->format('Y');
$monthId = $day->getDay()->format('m');
$totalsId = $yearId.$monthId;
if (!array_key_exists('years', $userYear)) {
$userYear['years'] = [];
}
if (!array_key_exists($yearId, $userYear['years'])) {
$userYear['years'][$yearId] = ['year' => $yearId];
}
if (!array_key_exists('months', $userYear['years'][$yearId])) {
$userYear['years'][$yearId]['months'] = [];
}
if (!array_key_exists($monthId, $userYear['years'][$yearId]['months'])) {
$userYear['years'][$yearId]['months'][$monthId] = ['month' => $monthId, 'totalDuration' => 0];
}
if (!array_key_exists($totalsId, $totals)) {
$totals[$totalsId] = 0;
}
$totals[$totalsId] += $day->getTotalDuration();
$userYear['years'][$yearId]['months'][$monthId]['totalDuration'] += $day->getTotalDuration();;
}
$userYears[] = $userYear;
}
}
$rows = $userYears;
*/
return $this->render('reporting/report_user_list_monthly.html.twig', [
'report_title' => 'report_yearly_users',
'box_id' => 'yearly-user-list-reporting-box',
'form' => $form->createView(),
'rows' => $rows,
'months' => $months,
'totals' => $totals,
'stats' => $monthStats,
'hasData' => $hasData,
]);
}
/**
* @Route(path="/monthly_users_list", name="report_monthly_users", methods={"GET","POST"})
*
* @param Request $request
* @return Response
* @throws Exception
*/
public function monthlyUsersList(Request $request): Response
public function monthlyUsersList(Request $request, TimesheetStatisticService $statisticService): Response
{
$currentUser = $this->getUser();
$dateTimeFactory = $this->getDateTimeFactory();
$localeFormats = $this->getLocaleFormats($request->getLocale());
$query = new UserQuery();
$query->setCurrentUser($currentUser);
$allUsers = $this->userRepository->getUsersForQuery($query);
$rows = [];
$values = new MonthlyUserList();
$values->setDate($dateTimeFactory->getStartOfMonth());
$form = $this->createForm(MonthlyUserListForm::class, $values, [
'timezone' => $dateTimeFactory->getTimezone()->getName(),
'start_date' => $values->getDate(),
'format' => $localeFormats->getDateTypeFormat(),
]);
$form->submit($request->query->all(), false);
@@ -234,71 +151,50 @@ final class ReportUsersListController extends AbstractController
$next = clone $start;
$next->modify('+1 month');
foreach ($allUsers as $user) {
$rows[] = [
'days' => $this->timesheetRepository->getDailyStats($user, $start, $end),
'user' => $user
];
$dayStats = [];
$hasData = true;
if (!empty($allUsers)) {
$dayStats = $statisticService->getDailyStatistics($start, $end, $allUsers);
}
$days = [];
$totals = [];
if (isset($rows[0])) {
/** @var Day $day */
foreach ($rows[0]['days'] as $day) {
$days[$day->getDay()->format('Ymd')] = $day->getDay();
}
foreach ($rows as $row) {
foreach ($row['days'] as $day) {
$totalsId = $day->getDay()->format('Ymd');
if (!isset($totals[$totalsId])) {
$totals[$totalsId] = 0;
}
$totals[$totalsId] += $day->getTotalDuration();
}
}
if (empty($dayStats)) {
$dayStats = [new DailyStatistic($start, $end, $currentUser)];
$hasData = false;
}
return $this->render('reporting/report_user_list.html.twig', [
'report_title' => 'report_monthly_users',
'box_id' => 'monthly-user-list-reporting-box',
'form' => $form->createView(),
'rows' => $rows,
'days' => $days,
'totals' => $totals,
'current' => $start,
'next' => $next,
'previous' => $previous,
'subReportDate' => $values->getDate(),
'subReportRoute' => 'report_user_month',
'stats' => $dayStats,
'hasData' => $hasData,
]);
}
/**
* @Route(path="/weekly_users_list", name="report_weekly_users", methods={"GET","POST"})
*
* @param Request $request
* @return Response
* @throws Exception
*/
public function weeklyUsersList(Request $request): Response
public function weeklyUsersList(Request $request, TimesheetStatisticService $statisticService): Response
{
$currentUser = $this->getUser();
$dateTimeFactory = $this->getDateTimeFactory();
$localeFormats = $this->getLocaleFormats($request->getLocale());
$query = new UserQuery();
$query->setCurrentUser($currentUser);
$allUsers = $this->userRepository->getUsersForQuery($query);
$rows = [];
$values = new WeeklyUserList();
$values->setDate($dateTimeFactory->getStartOfWeek());
$form = $this->createForm(WeeklyUserListForm::class, $values, [
'timezone' => $dateTimeFactory->getTimezone()->getName(),
'start_date' => $values->getDate(),
'format' => $localeFormats->getDateTypeFormat(),
]);
$form->submit($request->query->all(), false);
@@ -320,42 +216,29 @@ final class ReportUsersListController extends AbstractController
$next = clone $start;
$next->modify('+1 week');
foreach ($allUsers as $user) {
$rows[] = [
'days' => $this->timesheetRepository->getDailyStats($user, $start, $end),
'user' => $user
];
$dayStats = [];
$hasData = true;
if (!empty($allUsers)) {
$dayStats = $statisticService->getDailyStatistics($start, $end, $allUsers);
}
$days = [];
$totals = [];
if (isset($rows[0])) {
/** @var Day $day */
foreach ($rows[0]['days'] as $day) {
$days[$day->getDay()->format('Ymd')] = $day->getDay();
}
foreach ($rows as $row) {
foreach ($row['days'] as $day) {
$totalsId = $day->getDay()->format('Ymd');
if (!isset($totals[$totalsId])) {
$totals[$totalsId] = 0;
}
$totals[$totalsId] += $day->getTotalDuration();
}
}
if (empty($dayStats)) {
$dayStats = [new DailyStatistic($start, $end, $currentUser)];
$hasData = false;
}
return $this->render('reporting/report_user_list.html.twig', [
'report_title' => 'report_weekly_users',
'box_id' => 'weekly-user-list-reporting-box',
'form' => $form->createView(),
'rows' => $rows,
'days' => $days,
'totals' => $totals,
'current' => $start,
'next' => $next,
'previous' => $previous,
'subReportDate' => $values->getDate(),
'subReportRoute' => 'report_user_week',
'stats' => $dayStats,
'hasData' => $hasData,
]);
}
}