<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Roles;
use App\Entity\Timetable;
use App\Entity\User;
use App\Services\ClubService;
use App\Services\SessionService;
use App\Services\TimetableService;
use App\Services\UserService;
use App\ValueObjects\Timetable\TimetableFilter;
use DateTimeImmutable;
use DateTime;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Throwable;
use Webmozart\Assert\Assert;
use Doctrine\ORM\EntityManagerInterface;
/**
* Class TimetableController
* @package App\Controller
* @IsGranted ("ROLE_USER")
*/
class TimetableController extends AbstractController
{
/** @var UserService */
private UserService $userService;
/** @var TranslatorInterface */
private TranslatorInterface $translator;
/** @var TimetableService */
private TimetableService $timetableService;
/** @var SessionService */
private SessionService $sessionService;
/** @var ClubService */
private ClubService $clubService;
private string $projectName;
public function __construct(UserService $userService, TimetableService $timetableService, TranslatorInterface $translator, SessionService $sessionService, ClubService $clubService, string $projectName, EntityManagerInterface $entityManager)
{
$this->userService = $userService;
$this->translator = $translator;
$this->timetableService = $timetableService;
$this->sessionService = $sessionService;
$this->clubService = $clubService;
$this->projectName = $projectName;
$this->entityManager = $entityManager;
}
/**
* @Route(name="app_timetable_check_online", path="/users/healthcheck/online/check", methods={"GET"})
*/
public function checkOnline(): JsonResponse
{
try {
/** @var User $user */
$user = $this->getUser();
Assert::notEmpty($user, $this->translator->trans('User not found'));
if (is_null($user->getLastActionTime())) {
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
if($user->isTimetableEnabled()){
/** @var Timetable $lastTimetableRecord */
$lastTimetableRecord = $user->getTimetables()->last();
$currentTime = (new DateTime())->format("H:i");
if($currentTime > $user->getFinishWorkingTime()){
throw new Exception($this->translator->trans("User don't use cashdesk now"));
}
$day_start = $lastTimetableRecord->getStartDatetime()->format('d');
$day_diff = 0;
if(!is_null($user->getLastActionTime())){
$day_last_action = $user->getLastActionTime()->format('d');
$day_diff = $day_last_action - $day_start;
}
$current_day = date("d", time());
$day_finish = $lastTimetableRecord->getStartDatetime()->format('Y-m-d') .' '. $user->getFinishWorkingTime() . ':00';
if($day_diff > 0 || ($current_day - $day_start) > 0){
$date_finish = (new DateTimeImmutable())->setTimestamp(strtotime($day_finish));
$this->userService->clearLastActionTime($user);
$this->timetableService->finish($user, $date_finish);
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
}
if ($this->timetableService->isUserLogoutRequired($user) || !$user->isWorkingTimeNow()) {
$this->userService->releaseCurrentCashdesk($user);
$this->userService->clearLastActionTime($user);
$this->timetableService->finish($user);
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
if ($this->timetableService->isUserActionRequired($user)) {
$response = [
'success' => true,
'actionRequired' => true,
'soundRequired' => true,
];
return new JsonResponse($response);
}
return new JsonResponse(
[
'success' => true,
]
);
} catch (Throwable $t) {
return new JsonResponse([
'success' => false,
'message' => $t->getMessage()
]);
}
}
/**
* @Route(name="app_timetable_confirm_online", path="/users/healthcheck/online/confirm", methods={"POST"})
*/
public function confirmOnline(): JsonResponse
{
try {
/** @var User $user */
$user = $this->getUser();
Assert::notEmpty($user, $this->translator->trans('User not found'));
if (is_null($user->getLastActionTime())) {
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
if($user->isTimetableEnabled()){
/** @var Timetable $lastTimetableRecord */
$lastTimetableRecord = $user->getTimetables()->last();
$currentTime = (new DateTime())->format("H:i");
if($currentTime > $user->getFinishWorkingTime()){
throw new Exception($this->translator->trans("User don't use cashdesk now"));
}
$day_start = $lastTimetableRecord->getStartDatetime()->format('d');
$day_diff = 0;
if(!is_null($user->getLastActionTime())){
$day_last_action = $user->getLastActionTime()->format('d');
$day_diff = $day_last_action - $day_start;
}
$current_day = date("d", time());
$day_finish = $lastTimetableRecord->getStartDatetime()->format('Y-m-d') .' '. $user->getFinishWorkingTime() . ':00';
if($day_diff > 0 || ($current_day - $day_start) > 0){
$date_finish = (new DateTimeImmutable())->setTimestamp(strtotime($day_finish));
$this->userService->clearLastActionTime($user);
$this->timetableService->finish($user, $date_finish);
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
}
if ($this->timetableService->isUserLogoutRequired($user)) {
$this->userService->releaseCurrentCashdesk($user);
$this->userService->clearLastActionTime($user);
$this->timetableService->finish($user);
$this->sessionService->invalidateAllUsersSessions($user);
throw new Exception($this->translator->trans("Session expired. Please, login again"));
}
$this->userService->updateLastActionTime($user);
return new JsonResponse(
[
'success' => true,
]
);
} catch (Throwable $t) {
return new JsonResponse([
'success' => false,
'message' => $t->getMessage()
]);
}
}
/**
* @Route(name="app_timetable_personal_report", path="/report/timetables/personal")
* @IsGranted("ROLE_CABINET_TIMETABLE_REPORTS")
* @param Request $request
* @return Response
*/
public function personalReport(Request $request): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$yesterday = time() - 60 * 60 * 24 * 30;
$filterStartDate = $request->request->has("start_date") ? strtotime(filter_var($request->request->get("start_date"), FILTER_SANITIZE_STRING)) : mktime(0, 0, 0, intval(date('m', $yesterday)), intval(date('d', $yesterday)), intval(date('Y', $yesterday)));
$filterFinishDate = $request->request->has("finish_date") ? strtotime(filter_var($request->request->get("finish_date"), FILTER_SANITIZE_STRING)) : mktime(23, 59, 59, intval(date('m')), intval(date('d')), intval(date('Y')));
$filterUserId = $request->request->getInt('user_id');
$export = $request->request->get('export', false);
$filter = new TimetableFilter();
$filter
->setAllowedUsersList($currentUser->getAllowedUsersId())
->setStartDate($filterStartDate)
->setFinishDate($filterFinishDate)
->setMinimalDuration(10)
->setUserId($filterUserId);
if (!empty($filterUserId)) {
Assert::inArray($filterUserId, $currentUser->getAllowedUsersId(), $this->translator->trans('Access denied'));
}
$personalReport = $this->timetableService->getPersonalReport($filter);
if ($this->isGranted(Roles::ROLE_EXPORT_TO_EXCEL) && "xls" === $export) {
$this->timetableService->personalExportToXls($personalReport);
}
return $this->render('timetables/personal_report/index.html.twig', [
'filter' => $filter,
'users' => $this->userService->getAllowedUsersList(),
'personalReport' => $personalReport,
]);
}
/**
* @Route(name="app_timetable_full_report", path="/report/timetables/full")
* @IsGranted("ROLE_CABINET_TIMETABLE_REPORTS")
* @param Request $request
* @return Response
*/
public function fullReport(Request $request): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$submit = $request->request->getInt('submit');
$filterYear = $request->request->getInt('year', intval(date('Y')));
$filterMonth = $request->request->getInt('month', intval(date('m')));
$export = $request->request->get('export', false);
$clubs = $request->request->get('clubs');
$fullReport = [];
$filter = new TimetableFilter();
if (!empty($submit) || !empty($export)) {
$monthStart = mktime(0, 0, 0, $filterMonth, 1, $filterYear);
$monthFinish = mktime(23, 59, 59, $filterMonth, intval(date('t', $monthStart)), $filterYear);
$filter
->setAllowedClubsList($currentUser->getAllowedClubsId())
->setClubsList($clubs)
->setAllowedUsersList($currentUser->getAllowedUsersId())
->setYear($filterYear)
->setMonth($filterMonth)
->setStartDate($monthStart)
->setFinishDate($monthFinish);
$fullReport = $this->timetableService->getFullReport($filter);
if ($this->isGranted(Roles::ROLE_EXPORT_TO_EXCEL) && "xls" === $export) {
$this->timetableService->fullExportToXls($fullReport, $this->clubService);
}
}
return $this->render('timetables/full_report/index.html.twig', [
'filter' => $filter,
'users' => $this->userService->getAllowedUsersList(),
'clubs' => $this->clubService->getAllowedClubsList(),
'years' => [date('Y'), date('Y') - 1],
'fullReport' => $fullReport,
]);
}
/**
* @Route(name="app_timetable_full_report_new", path="/report/timetables/full_new")
* @IsGranted("ROLE_CABINET_TIMETABLE_REPORTS")
* @param Request $request
* @return Response
*/
public function fullReportNew(Request $request): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$submit = $request->request->getInt('submit');
$filterYear = $request->request->getInt('year', intval(date('Y')));
$filterMonth = $request->request->getInt('month', intval(date('m')));
$export = $request->request->get('export', false);
$clubs = $request->request->get('clubs');
$fullReport = [];
$filter = new TimetableFilter();
if (!empty($submit) || !empty($export)) {
$monthStart = mktime(0, 0, 0, $filterMonth, 1, $filterYear);
$monthFinish = mktime(23, 59, 59, $filterMonth, intval(date('t', $monthStart)), $filterYear);
$filter
->setAllowedClubsList($currentUser->getAllowedClubsId())
->setClubsList($clubs)
->setAllowedUsersList($currentUser->getAllowedUsersId())
->setYear($filterYear)
->setMonth($filterMonth)
->setStartDate($monthStart)
->setFinishDate($monthFinish);
$fullReport = $this->timetableService->getFullReportNew($filter);
if ($this->isGranted(Roles::ROLE_EXPORT_TO_EXCEL) && "xls" === $export) {
$this->timetableService->fullNewExportToXls($fullReport, $this->clubService);
}
}
return $this->render('timetables/full_report_new/index.html.twig', [
'filter' => $filter,
'users' => $this->userService->getAllowedUsersList(),
'clubs' => $this->clubService->getAllowedClubsList(),
'years' => [date('Y'), date('Y') - 1],
'fullReport' => $fullReport,
]);
}
/**
* @Route(name="app_timetable_full_report_hours_worked", path="/report/timetables/full_hours_worked")
* @IsGranted("ROLE_CABINET_TIMETABLE_REPORTS")
* @param Request $request
* @return Response
*/
public function fullReportHoursWorked(Request $request): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$submit = $request->request->getInt('submit');
$filterYear = $request->request->getInt('year', intval(date('Y')));
$filterMonth = $request->request->getInt('month', intval(date('m')));
$export = $request->request->get('export', false);
$clubs = $request->request->get('clubs');
$fullReport = $cashier_payments = [];
$filter = new TimetableFilter();
if (!empty($submit) || !empty($export)) {
$monthStart = mktime(0, 0, 0, $filterMonth, 1, $filterYear);
$monthFinish = mktime(23, 59, 59, $filterMonth, intval(date('t', $monthStart)), $filterYear);
$filter
->setAllowedClubsList($currentUser->getAllowedClubsId())
->setClubsList($clubs)
->setAllowedUsersList($currentUser->getAllowedUsersId())
->setYear($filterYear)
->setMonth($filterMonth)
->setStartDate($monthStart)
->setFinishDate($monthFinish);
$fullReport = $this->timetableService->getFullReport($filter);
$cashier_payments = $this->timetableService->getCashierPayments($filter);
if ($this->isGranted(Roles::ROLE_EXPORT_TO_EXCEL) && "xls" === $export) {
$this->timetableService->fullHoursWorkedExportToXls($fullReport, $cashier_payments, $this->clubService);
}
}
return $this->render('timetables/full_report/index_hours_worked.html.twig', [
'filter' => $filter,
'users' => $this->userService->getAllowedUsersList(),
'clubs' => $this->clubService->getAllowedClubsList(),
'years' => [date('Y'), date('Y') - 1],
'fullReport' => $fullReport,
'cashier_payments' => $cashier_payments,
]);
}
/**
* @Route(name="app_timetable_last_active", path="/report/timetables/last_active")
* @IsGranted("ROLE_CABINET_TIMETABLE_REPORTS")
* @param Request $request
* @return Response
*/
public function ReportWorkLastActive(Request $request): Response
{
/** @var User $currentUser */
$currentUser = $this->getUser();
$yesterday = time() - 60 * 60 * 24;
$filterStartDate = $request->request->has("start_date") ? strtotime(filter_var($request->request->get("start_date"), FILTER_SANITIZE_STRING)) : mktime(0, 0, 0, intval(date('m', $yesterday)), intval(date('d', $yesterday)), intval(date('Y', $yesterday)));
$filterFinishDate = $request->request->has("finish_date") ? strtotime(filter_var($request->request->get("finish_date"), FILTER_SANITIZE_STRING)) : mktime(23, 59, 59, intval(date('m')), intval(date('d')), intval(date('Y')));
$filterUserList = $request->request->get('users') ?? [];
$filterClubList = $request->request->get('clubs') ?? [];
$export = $request->request->get('export', false);
$filter = new TimetableFilter();
$filter
->setAllowedUsersList($currentUser->getAllowedUsersId())
->setAllowedClubsList($currentUser->getAllowedClubsId())
->setStartDate($filterStartDate)
->setFinishDate($filterFinishDate);
// if($this->projectName != "ground_cashdesk_dom"){
// die;
// }
/*timetables*/
$timetables = $timetables_tmp = $payments = [];
if(sizeof($filterUserList) > 0 || sizeof($filterClubList) > 0) {
$sql = "SELECT
`users`.`username` AS `username`, `clubs`.`title` AS `clubtitle`, `timetables`.*
FROM `timetables`
LEFT JOIN `users` ON `users`.id = `timetables`.`user_id`
LEFT JOIN `clubs` ON `clubs`.id = `timetables`.`club_id`
WHERE `start_datetime` >= '".date('Y-m-d H:i:s', $filterStartDate)."'
AND `finish_datetime` <= '".date('Y-m-d H:i:s', $filterFinishDate)."'
AND `duration` > 10";
if (sizeof($filterUserList) > 0) {
$sql .= " AND user_id IN (" . implode(', ', $filterUserList) . ")";
}
if (sizeof($filterClubList) > 0) {
$sql .= " AND club_id IN (" . implode(', ', $filterClubList) . ")";
}
$prepareStatement = $this->entityManager->getConnection()->prepare($sql);
$result = $prepareStatement->executeQuery();
if ($result->rowCount() > 0) {
$row = $result->fetchAllAssociative();
foreach ($row as $value) {
$timetables_tmp[$value["user_id"]][date("Y-m-d", strtotime($value["start_datetime"]))][] = $value;
}
}
foreach ($timetables_tmp as $user_id => $val) {
foreach ($val as $day => $value) {
foreach ($value as $item) {
$timetables[$user_id][$day]["timetable"][$item["start_datetime"]] = [
"start" => $item["start_datetime"],
"finish" => $item["finish_datetime"],
"sql" => " AND `opdate` BETWEEN '".$item["start_datetime"]."' AND '".$item["finish_datetime"]."'"
];
$timetables[$user_id][$day]["username"] = $item["username"];
$timetables[$user_id][$day]["clubtitle"] = $item["clubtitle"];
}
}
}
foreach ($timetables as $user_id => $val) {
foreach ($val as $day => $value) {
foreach ($value as $item) {
foreach ($item as $rec) {
$sql = "
SELECT * FROM `payments`
WHERE `operator_id` = " . $user_id . "
".$rec["sql"]."
ORDER BY id DESC LIMIT 1
";
$prepareStatement = $this->entityManager->getConnection()->prepare($sql);
$result = $prepareStatement->executeQuery();
if ($result->rowCount() > 0) {
$row = $result->fetchAssociative();
$payments[$user_id][$day][$rec["start"]] = [
"start" => $rec["start"],
"finish" => $rec["finish"],
"last" => $row["opdate"]
];
}
}
}
}
}
}
/***********/
if ($this->isGranted(Roles::ROLE_EXPORT_TO_EXCEL) && "xls" === $export) {
$this->timetableService->lastActiveToXls($timetables, $payments);
}
return $this->render('timetables/last_active/index.html.twig', [
'filter' => $filter,
'users' => $this->userService->getAllowedUsersList(),
'clubs' => $this->clubService->getAllowedClubsList(),
'filterUserList' => $filterUserList,
'filterClubList' => $filterClubList,
'timetables' => $timetables,
'payments' => $payments,
]);
}
}