Release 2.0.18 (#4003)
* prevent too long values for user preferences * add chart value 0 to y-axis if last value > 0, to always display the zero line (project details) * add user-preferences to invoice hydrator * DateTime vs DateTimeInterface * simplify permission config * fix query for teamleads limiting to only selected teams not possible
This commit is contained in:
@@ -20,6 +20,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstract
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormTypeInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
@@ -47,19 +48,41 @@ abstract class AbstractController extends BaseAbstractController implements Serv
|
||||
return $this->container->get('translator');
|
||||
}
|
||||
|
||||
protected function createSearchForm(string $type = FormType::class, $data = null, array $options = []): FormInterface
|
||||
/**
|
||||
* @template TFormType of FormTypeInterface<TData>
|
||||
* @template TData of mixed
|
||||
* @param class-string<TFormType> $type
|
||||
* @param TData $data
|
||||
* @param array<mixed> $options
|
||||
* @return FormInterface<TData>
|
||||
*/
|
||||
protected function createSearchForm(string $type, mixed $data, array $options = []): FormInterface
|
||||
{
|
||||
return $this->createFormForGetRequest($type, $data, $options);
|
||||
}
|
||||
|
||||
protected function createFormForGetRequest(string $type = FormType::class, $data = null, array $options = []): FormInterface
|
||||
/**
|
||||
* @template TFormType of FormTypeInterface<TData>
|
||||
* @template TData of mixed
|
||||
* @param class-string<TFormType> $type
|
||||
* @param TData $data
|
||||
* @param array<mixed> $options
|
||||
* @return FormInterface<TData>
|
||||
*/
|
||||
protected function createFormForGetRequest(string $type, mixed $data, array $options = []): FormInterface
|
||||
{
|
||||
return $this->container
|
||||
->get('form.factory')
|
||||
->createNamed('', $type, $data, array_merge(['method' => 'GET'], $options));
|
||||
return $this->container->get('form.factory')->createNamed('', $type, $data, array_merge(['method' => 'GET'], $options)); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
protected function createFormWithName(string $name, string $type, mixed $data = null, array $options = []): FormInterface
|
||||
/**
|
||||
* @template TFormType of FormTypeInterface<TData>
|
||||
* @template TData of mixed
|
||||
* @param class-string<TFormType> $type
|
||||
* @param TData|null $data
|
||||
* @param array<mixed> $options
|
||||
* @return FormInterface<TData|null>
|
||||
*/
|
||||
protected function createFormWithName(string $name, string $type = FormType::class, mixed $data = null, array $options = []): FormInterface
|
||||
{
|
||||
return $this->container->get('form.factory')->createNamed($name, $type, $data, $options);
|
||||
}
|
||||
@@ -166,6 +189,9 @@ abstract class AbstractController extends BaseAbstractController implements Serv
|
||||
|
||||
/**
|
||||
* Handles exception flash messages for failed update/create actions.
|
||||
* @param \Exception $exception
|
||||
* @param FormInterface $form
|
||||
* @return void
|
||||
*/
|
||||
protected function handleFormUpdateException(\Exception $exception, FormInterface $form): void
|
||||
{
|
||||
|
||||
@@ -414,6 +414,10 @@ final class ActivityController extends AbstractController
|
||||
return $writer->getFileResponse($spreadsheet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActivityQuery $query
|
||||
* @return FormInterface<ActivityQuery>
|
||||
*/
|
||||
private function getToolbarForm(ActivityQuery $query): FormInterface
|
||||
{
|
||||
return $this->createSearchForm(ActivityToolbarForm::class, $query, [
|
||||
@@ -423,6 +427,10 @@ final class ActivityController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
* @return FormInterface<ActivityEditForm>
|
||||
*/
|
||||
private function createEditForm(Activity $activity): FormInterface
|
||||
{
|
||||
$currency = $this->configuration->getCustomerDefaultCurrency();
|
||||
|
||||
@@ -505,6 +505,10 @@ final class CustomerController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerQuery $query
|
||||
* @return FormInterface<CustomerQuery>
|
||||
*/
|
||||
private function getToolbarForm(CustomerQuery $query): FormInterface
|
||||
{
|
||||
return $this->createSearchForm(CustomerToolbarForm::class, $query, [
|
||||
@@ -514,6 +518,10 @@ final class CustomerController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CustomerComment $comment
|
||||
* @return FormInterface<CustomerComment>
|
||||
*/
|
||||
private function getCommentForm(CustomerComment $comment): FormInterface
|
||||
{
|
||||
if (null === $comment->getId()) {
|
||||
@@ -526,6 +534,10 @@ final class CustomerController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Customer $customer
|
||||
* @return FormInterface<Customer>
|
||||
*/
|
||||
private function createEditForm(Customer $customer): FormInterface
|
||||
{
|
||||
$event = new CustomerMetaDefinitionEvent($customer);
|
||||
|
||||
@@ -157,6 +157,11 @@ final class ExportController extends AbstractController
|
||||
return $this->export->getExportItems($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ExportQuery $query
|
||||
* @param string $method
|
||||
* @return FormInterface<ExportQuery>
|
||||
*/
|
||||
private function getToolbarForm(ExportQuery $query, string $method): FormInterface
|
||||
{
|
||||
return $this->createSearchForm(ExportToolbarForm::class, $query, [
|
||||
|
||||
@@ -17,7 +17,7 @@ use App\Model\Statistic\StatisticDate;
|
||||
use App\Repository\ActivityRepository;
|
||||
use App\Repository\ProjectRepository;
|
||||
use App\Timesheet\TimesheetStatisticService;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
|
||||
abstract class AbstractUserReportController extends AbstractController
|
||||
{
|
||||
@@ -35,17 +35,17 @@ abstract class AbstractUserReportController extends AbstractController
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getStatisticDataRaw(DateTime $begin, DateTime $end, User $user): array
|
||||
protected function getStatisticDataRaw(DateTimeInterface $begin, DateTimeInterface $end, User $user): array
|
||||
{
|
||||
return $this->statisticService->getDailyStatisticsGrouped($begin, $end, [$user]);
|
||||
}
|
||||
|
||||
protected function createStatisticModel(DateTime $begin, DateTime $end, User $user): DateStatisticInterface
|
||||
protected function createStatisticModel(DateTimeInterface $begin, DateTimeInterface $end, User $user): DateStatisticInterface
|
||||
{
|
||||
return new DailyStatistic($begin, $end, $user);
|
||||
}
|
||||
|
||||
protected function prepareReport(DateTime $begin, DateTime $end, User $user): array
|
||||
protected function prepareReport(DateTimeInterface $begin, DateTimeInterface $end, User $user): array
|
||||
{
|
||||
$data = $this->getStatisticDataRaw($begin, $end, $user);
|
||||
|
||||
|
||||
@@ -105,7 +105,9 @@ final class ReportUsersYearController extends AbstractController
|
||||
$values->setDate(clone $defaultDate);
|
||||
}
|
||||
|
||||
/** @var \DateTime $start */
|
||||
$start = $values->getDate();
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -16,6 +16,7 @@ use App\Model\MonthlyStatistic;
|
||||
use App\Reporting\YearByUser\YearByUser;
|
||||
use App\Reporting\YearByUser\YearByUserForm;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use Exception;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -75,6 +76,7 @@ final class UserYearController extends AbstractUserReportController
|
||||
$values->setDate(clone $defaultDate);
|
||||
}
|
||||
|
||||
/** @var \DateTimeInterface $start */
|
||||
$start = $values->getDate();
|
||||
// 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
|
||||
@@ -82,10 +84,10 @@ final class UserYearController extends AbstractUserReportController
|
||||
|
||||
$selectedUser = $values->getUser();
|
||||
|
||||
$previous = clone $start;
|
||||
$previous = DateTime::createFromInterface($start);
|
||||
$previous->modify('-1 year');
|
||||
|
||||
$next = clone $start;
|
||||
$next = DateTime::createFromInterface($start);
|
||||
$next->modify('+1 year');
|
||||
|
||||
$data = $this->prepareReport($start, $end, $selectedUser);
|
||||
@@ -105,12 +107,12 @@ final class UserYearController extends AbstractUserReportController
|
||||
];
|
||||
}
|
||||
|
||||
protected function getStatisticDataRaw(DateTime $begin, DateTime $end, User $user): array
|
||||
protected function getStatisticDataRaw(DateTimeInterface $begin, DateTimeInterface $end, User $user): array
|
||||
{
|
||||
return $this->statisticService->getMonthlyStatisticsGrouped($begin, $end, [$user]);
|
||||
}
|
||||
|
||||
protected function createStatisticModel(DateTime $begin, DateTime $end, User $user): DateStatisticInterface
|
||||
protected function createStatisticModel(DateTimeInterface $begin, DateTimeInterface $end, User $user): DateStatisticInterface
|
||||
{
|
||||
return new MonthlyStatistic($begin, $end, $user);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user