diff --git a/src/Controller/CalendarController.php b/src/Controller/CalendarController.php index b484a8f7..66bd24f1 100644 --- a/src/Controller/CalendarController.php +++ b/src/Controller/CalendarController.php @@ -11,8 +11,12 @@ namespace App\Controller; use App\Calendar\CalendarService; use App\Configuration\SystemConfiguration; +use App\Entity\User; +use App\Form\CalendarForm; use App\Timesheet\TrackingModeService; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; /** @@ -24,20 +28,43 @@ use Symfony\Component\Routing\Annotation\Route; class CalendarController extends AbstractController { private $calendarService; + private $configuration; + private $service; - public function __construct(CalendarService $calendarService) + public function __construct(CalendarService $calendarService, SystemConfiguration $configuration, TrackingModeService $service) { $this->calendarService = $calendarService; + $this->configuration = $configuration; + $this->service = $service; } /** * @Route(path="/", name="calendar", methods={"GET"}) + * @Route(path="/{profile}", name="calendar_user", methods={"GET"}) */ - public function userCalendar(SystemConfiguration $configuration, TrackingModeService $service) + public function userCalendar(Request $request): Response { - $mode = $service->getActiveMode(); + $form = null; + $profile = $this->getUser(); + + if ($this->isGranted('view_other_timesheet')) { + $form = $this->createFormForGetRequest(CalendarForm::class, ['user' => $profile], [ + 'action' => $this->generateUrl('calendar'), + ]); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $values = $form->getData(); + if ($values['user'] instanceof User) { + $profile = $values['user']; + } + } + } + + $mode = $this->service->getActiveMode(); $factory = $this->getDateTimeFactory(); - $defaultStart = $factory->createDateTime($configuration->getTimesheetDefaultBeginTime()); + $defaultStart = $factory->createDateTime($this->configuration->getTimesheetDefaultBeginTime()); $config = $this->calendarService->getConfiguration(); @@ -46,16 +73,18 @@ class CalendarController extends AbstractController if ($mode->canEditBegin()) { try { - $dragAndDrop = $this->calendarService->getDragAndDropResources($this->getUser()); + $dragAndDrop = $this->calendarService->getDragAndDropResources($profile); } catch (\Exception $ex) { $this->logException($ex); } } return $this->render('calendar/user.html.twig', [ + 'form' => ($form === null ? null : $form->createView()), + 'user' => $profile, 'config' => $config, 'dragAndDrop' => $dragAndDrop, - 'google' => $this->calendarService->getGoogleSources($this->getUser()), + 'google' => $this->calendarService->getGoogleSources($profile), 'now' => $factory->createDateTime(), 'defaultStartTime' => $defaultStart->format('h:i:s'), 'is_punch_mode' => $isPunchMode, diff --git a/src/Controller/TimesheetAbstractController.php b/src/Controller/TimesheetAbstractController.php index 7dc3785e..2f2a42bb 100644 --- a/src/Controller/TimesheetAbstractController.php +++ b/src/Controller/TimesheetAbstractController.php @@ -23,10 +23,9 @@ use App\Form\MultiUpdate\MultiUpdateTableDTO; use App\Form\MultiUpdate\TimesheetMultiUpdate; use App\Form\MultiUpdate\TimesheetMultiUpdateDTO; use App\Form\TimesheetEditForm; +use App\Form\TimesheetPreCreateForm; use App\Form\Toolbar\TimesheetExportToolbarForm; use App\Form\Toolbar\TimesheetToolbarForm; -use App\Repository\ActivityRepository; -use App\Repository\ProjectRepository; use App\Repository\Query\TimesheetQuery; use App\Repository\TagRepository; use App\Repository\TimesheetRepository; @@ -147,48 +146,14 @@ abstract class TimesheetAbstractController extends AbstractController ]); } - protected function getTags(TagRepository $tagRepository, $tagNames) - { - $tags = []; - if (!\is_array($tagNames)) { - $tagNames = explode(',', $tagNames); - } - foreach ($tagNames as $tagName) { - $tag = $tagRepository->findTagByName($tagName); - if (!$tag) { - $tag = new Tag(); - $tag->setName($tagName); - } - $tags[] = $tag; - } - - return $tags; - } - - protected function create(Request $request, string $renderTemplate, ProjectRepository $projectRepository, ActivityRepository $activityRepository, TagRepository $tagRepository): Response + protected function create(Request $request, string $renderTemplate): Response { $entry = $this->service->createNewTimesheet($this->getUser()); - if ($request->query->get('project')) { - $project = $projectRepository->find($request->query->get('project')); - $entry->setProject($project); - } - - if ($request->query->get('activity')) { - $activity = $activityRepository->find($request->query->get('activity')); - $entry->setActivity($activity); - } - - if ($request->query->get('description')) { - $description = $request->query->get('description'); - $entry->setDescription($description); - } - - if ($request->query->get('tags')) { - foreach ($this->getTags($tagRepository, $request->query->get('tags')) as $tag) { - $entry->addTag($tag); - } - } + $preForm = $this->createFormForGetRequest(TimesheetPreCreateForm::class, $entry, [ + 'include_user' => $this->includeUserInForms('create'), + ]); + $preForm->submit($request->query->all(), false); $this->service->prepareNewTimesheet($entry, $request); $createForm = $this->getCreateForm($entry); diff --git a/src/Controller/TimesheetController.php b/src/Controller/TimesheetController.php index df14b2cc..3c98e26b 100644 --- a/src/Controller/TimesheetController.php +++ b/src/Controller/TimesheetController.php @@ -13,9 +13,6 @@ use App\Entity\Timesheet; use App\Event\TimesheetMetaDisplayEvent; use App\Export\ServiceExport; use App\Form\TimesheetEditForm; -use App\Repository\ActivityRepository; -use App\Repository\ProjectRepository; -use App\Repository\TagRepository; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -90,9 +87,9 @@ class TimesheetController extends TimesheetAbstractController * @Route(path="/create", name="timesheet_create", methods={"GET", "POST"}) * @Security("is_granted('create_own_timesheet')") */ - public function createAction(Request $request, ProjectRepository $projectRepository, ActivityRepository $activityRepository, TagRepository $tagRepository): Response + public function createAction(Request $request): Response { - return $this->create($request, 'timesheet/edit.html.twig', $projectRepository, $activityRepository, $tagRepository); + return $this->create($request, 'timesheet/edit.html.twig'); } protected function getCreateForm(Timesheet $entry): FormInterface diff --git a/src/Controller/TimesheetTeamController.php b/src/Controller/TimesheetTeamController.php index fcae6876..26bbbbdf 100644 --- a/src/Controller/TimesheetTeamController.php +++ b/src/Controller/TimesheetTeamController.php @@ -18,10 +18,7 @@ use App\Export\ServiceExport; use App\Form\Model\MultiUserTimesheet; use App\Form\TimesheetAdminEditForm; use App\Form\TimesheetMultiUserEditForm; -use App\Repository\ActivityRepository; -use App\Repository\ProjectRepository; use App\Repository\Query\TimesheetQuery; -use App\Repository\TagRepository; use Doctrine\Common\Collections\ArrayCollection; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security; use Symfony\Component\Form\FormInterface; @@ -83,9 +80,9 @@ class TimesheetTeamController extends TimesheetAbstractController * @Route(path="/create", name="admin_timesheet_create", methods={"GET", "POST"}) * @Security("is_granted('create_other_timesheet')") */ - public function createAction(Request $request, ProjectRepository $projectRepository, ActivityRepository $activityRepository, TagRepository $tagRepository): Response + public function createAction(Request $request): Response { - return $this->create($request, 'timesheet-team/edit.html.twig', $projectRepository, $activityRepository, $tagRepository); + return $this->create($request, 'timesheet-team/edit.html.twig'); } /** diff --git a/src/Form/CalendarForm.php b/src/Form/CalendarForm.php new file mode 100644 index 00000000..30ff216d --- /dev/null +++ b/src/Form/CalendarForm.php @@ -0,0 +1,34 @@ +add('user', UserType::class, [ + 'required' => false, + 'attr' => ['onchange' => 'this.form.submit()'] + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'csrf_protection' => false, + 'method' => 'GET', + ]); + } +} diff --git a/src/Form/TimesheetPreCreateForm.php b/src/Form/TimesheetPreCreateForm.php new file mode 100644 index 00000000..0233450c --- /dev/null +++ b/src/Form/TimesheetPreCreateForm.php @@ -0,0 +1,46 @@ +addProject($builder, true, null, null, ['required' => false]); + $this->addActivity($builder, null, null, ['required' => false]); + $builder->add('description', DescriptionType::class, ['required' => false]); + $builder->add('tags', TagsInputType::class, ['required' => false]); + if ($options['include_user']) { + $builder->add('user', UserType::class, ['required' => false]); + } + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'csrf_protection' => false, + 'include_user' => false, + 'method' => 'GET', + 'validation_groups' => ['none'] // otherwise the default timesheet validations would trigger + ]); + } +} diff --git a/src/Validator/Constraints/TimesheetZeroDurationValidator.php b/src/Validator/Constraints/TimesheetZeroDurationValidator.php index 6d7a8c40..b9d681cb 100644 --- a/src/Validator/Constraints/TimesheetZeroDurationValidator.php +++ b/src/Validator/Constraints/TimesheetZeroDurationValidator.php @@ -17,9 +17,6 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException; final class TimesheetZeroDurationValidator extends ConstraintValidator { - /** - * @var SystemConfiguration - */ private $configuration; public function __construct(SystemConfiguration $configuration) @@ -45,7 +42,16 @@ final class TimesheetZeroDurationValidator extends ConstraintValidator return; } - if ($timesheet->getDuration() == 0) { + if ($timesheet->isRunning()) { + return; + } + + $duration = 0; + if ($timesheet->getEnd() !== null && $timesheet->getBegin() !== null) { + $duration = $timesheet->getEnd()->getTimestamp() - $timesheet->getBegin()->getTimestamp(); + } + + if ($duration <= 0) { $this->context->buildViolation($constraint->message) ->atPath('duration') ->setTranslationDomain('validators') diff --git a/templates/calendar/user.html.twig b/templates/calendar/user.html.twig index 8b89cb22..c4c6fc62 100644 --- a/templates/calendar/user.html.twig +++ b/templates/calendar/user.html.twig @@ -11,8 +11,17 @@ {% block main %}