Release 2.13 (#4659)
This commit is contained in:
@@ -38,9 +38,7 @@ final class QuickEntryTimesheetValidator extends ConstraintValidator
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
$timesheet = $value;
|
||||
|
||||
if ($timesheet->getId() === null && $timesheet->getDuration(false) === null) {
|
||||
if ($value->getId() === null && $value->getDuration(false) === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -49,7 +47,7 @@ final class QuickEntryTimesheetValidator extends ConstraintValidator
|
||||
->getValidator()
|
||||
->inContext($this->context)
|
||||
->atPath('duration')
|
||||
->validate($timesheet, $innerConstraint, [Constraint::DEFAULT_GROUP]);
|
||||
->validate($value, $innerConstraint, [Constraint::DEFAULT_GROUP]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetBasicValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private SystemConfiguration $systemConfiguration)
|
||||
public function __construct(private readonly SystemConfiguration $systemConfiguration)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -36,10 +36,6 @@ final class TimesheetBasicValidator extends ConstraintValidator
|
||||
$this->validateActivityAndProject($value, $this->context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param ExecutionContextInterface $context
|
||||
*/
|
||||
protected function validateBeginAndEnd(TimesheetEntity $timesheet, ExecutionContextInterface $context): void
|
||||
{
|
||||
$begin = $timesheet->getBegin();
|
||||
@@ -64,10 +60,6 @@ final class TimesheetBasicValidator extends ConstraintValidator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param ExecutionContextInterface $context
|
||||
*/
|
||||
protected function validateActivityAndProject(TimesheetEntity $timesheet, ExecutionContextInterface $context): void
|
||||
{
|
||||
$activity = $timesheet->getActivity();
|
||||
|
||||
@@ -13,7 +13,7 @@ use App\Activity\ActivityStatisticService;
|
||||
use App\Configuration\LocaleService;
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Customer\CustomerStatisticService;
|
||||
use App\Entity\Timesheet;
|
||||
use App\Entity\Timesheet as TimesheetEntity;
|
||||
use App\Model\BudgetStatisticModel;
|
||||
use App\Project\ProjectStatisticService;
|
||||
use App\Repository\TimesheetRepository;
|
||||
@@ -29,53 +29,49 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(
|
||||
private SystemConfiguration $configuration,
|
||||
private CustomerStatisticService $customerStatisticService,
|
||||
private ProjectStatisticService $projectStatisticService,
|
||||
private ActivityStatisticService $activityStatisticService,
|
||||
private TimesheetRepository $timesheetRepository,
|
||||
private RateServiceInterface $rateService,
|
||||
private AuthorizationCheckerInterface $security,
|
||||
private LocaleService $localeService
|
||||
private readonly SystemConfiguration $configuration,
|
||||
private readonly CustomerStatisticService $customerStatisticService,
|
||||
private readonly ProjectStatisticService $projectStatisticService,
|
||||
private readonly ActivityStatisticService $activityStatisticService,
|
||||
private readonly TimesheetRepository $timesheetRepository,
|
||||
private readonly RateServiceInterface $rateService,
|
||||
private readonly AuthorizationCheckerInterface $security,
|
||||
private readonly LocaleService $localeService
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Timesheet $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetBudgetUsed)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetBudgetUsed::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof Timesheet)) {
|
||||
throw new UnexpectedTypeException($timesheet, Timesheet::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
if ($this->configuration->isTimesheetAllowOverbookingBudget()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$begin = $timesheet->getBegin();
|
||||
$begin = $value->getBegin();
|
||||
|
||||
// we can only work with stopped entries
|
||||
if ($begin === null || $timesheet->getEnd() === null || $timesheet->getUser() === null) {
|
||||
if ($begin === null || $value->getEnd() === null || $value->getUser() === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// budgets need only be calculated for billable records
|
||||
if (!$timesheet->isBillable()) {
|
||||
if (!$value->isBillable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this validator needs a project to calculate the rates
|
||||
if ($timesheet->getProject() === null) {
|
||||
if ($value->getProject() === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = $timesheet->getId();
|
||||
$id = $value->getId();
|
||||
|
||||
// when changing the date via the calendar and/or the API, the duration will not be reset by the
|
||||
// duration calculator (which runs after validation!) so we manually reset the duration before
|
||||
@@ -92,9 +88,9 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
// $timesheet->setDuration(null);
|
||||
// $duration = $timesheet->getDuration();
|
||||
|
||||
$duration = $timesheet->getCalculatedDuration();
|
||||
$duration = $value->getCalculatedDuration();
|
||||
|
||||
$timeRate = $this->rateService->calculate($timesheet);
|
||||
$timeRate = $this->rateService->calculate($value);
|
||||
$rate = $timeRate->getRate();
|
||||
|
||||
$activityDuration = $duration ?? 0;
|
||||
@@ -116,10 +112,10 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
// this could for example happen when export flag is changed OR if "prevent overbooking" config was recently activated and this is an old entry
|
||||
if ($duration === $rawData['duration'] &&
|
||||
$rate === $rawData['rate'] &&
|
||||
$timesheet->isBillable() === $rawData['billable'] &&
|
||||
$value->isBillable() === $rawData['billable'] &&
|
||||
$begin->format('Y.m.d') === $rawData['begin']->format('Y.m.d') &&
|
||||
$timesheet->getProject()->getId() === $projectId &&
|
||||
($timesheet->getActivity() === null || $timesheet->getActivity()->getId() === $activityId)
|
||||
$value->getProject()->getId() === $projectId &&
|
||||
($value->getActivity() === null || $value->getActivity()->getId() === $activityId)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -129,18 +125,18 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
// only subtract the previously logged data in case the record was billable
|
||||
// if it wasn't billable, then its values are not included in the statistic models used later on
|
||||
if ($rawData['billable']) {
|
||||
if (null !== $timesheet->getActivity() && $activityId === $timesheet->getActivity()->getId()) {
|
||||
if (null !== $value->getActivity() && $activityId === $value->getActivity()->getId()) {
|
||||
$activityDuration -= $rawData['duration'];
|
||||
$activityRate -= $rawData['rate'];
|
||||
}
|
||||
|
||||
if (null !== $timesheet->getProject()) {
|
||||
if ($projectId === $timesheet->getProject()->getId()) {
|
||||
if (null !== $value->getProject()) {
|
||||
if ($projectId === $value->getProject()->getId()) {
|
||||
$projectDuration -= $rawData['duration'];
|
||||
$projectRate -= $rawData['rate'];
|
||||
}
|
||||
|
||||
if ($customerId === $timesheet->getProject()->getCustomer()->getId()) {
|
||||
if ($customerId === $value->getProject()->getCustomer()->getId()) {
|
||||
$customerDuration -= $rawData['duration'];
|
||||
$customerRate -= $rawData['rate'];
|
||||
}
|
||||
@@ -153,23 +149,23 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
$now = new DateTime('now', $begin->getTimezone());
|
||||
$recordDate = $begin;
|
||||
|
||||
if (null !== ($activity = $timesheet->getActivity()) && $activity->hasBudgets()) {
|
||||
if (null !== ($activity = $value->getActivity()) && $activity->hasBudgets()) {
|
||||
$dateTime = $activity->isMonthlyBudget() ? $recordDate : $now;
|
||||
if ($activity->isMonthlyBudget() && $monthWasChanged) {
|
||||
$activityDuration = $duration;
|
||||
}
|
||||
$stat = $this->activityStatisticService->getBudgetStatisticModel($activity, $dateTime);
|
||||
$this->checkBudgets($constraint, $stat, $timesheet, $activityDuration, $activityRate, 'activity');
|
||||
$this->checkBudgets($constraint, $stat, $value, $activityDuration, $activityRate, 'activity');
|
||||
}
|
||||
|
||||
if (null !== ($project = $timesheet->getProject())) {
|
||||
if (null !== ($project = $value->getProject())) {
|
||||
if ($project->hasBudgets()) {
|
||||
$dateTime = $project->isMonthlyBudget() ? $recordDate : $now;
|
||||
if ($project->isMonthlyBudget() && $monthWasChanged) {
|
||||
$projectDuration = $duration;
|
||||
}
|
||||
$stat = $this->projectStatisticService->getBudgetStatisticModel($project, $dateTime);
|
||||
$this->checkBudgets($constraint, $stat, $timesheet, $projectDuration, $projectRate, 'project');
|
||||
$this->checkBudgets($constraint, $stat, $value, $projectDuration, $projectRate, 'project');
|
||||
}
|
||||
if (null !== ($customer = $project->getCustomer()) && $customer->hasBudgets()) {
|
||||
$dateTime = $customer->isMonthlyBudget() ? $recordDate : $now;
|
||||
@@ -177,12 +173,12 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
$customerDuration = $duration;
|
||||
}
|
||||
$stat = $this->customerStatisticService->getBudgetStatisticModel($customer, $dateTime);
|
||||
$this->checkBudgets($constraint, $stat, $timesheet, $customerDuration, $customerRate, 'customer');
|
||||
$this->checkBudgets($constraint, $stat, $value, $customerDuration, $customerRate, 'customer');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function checkBudgets(TimesheetBudgetUsed $constraint, BudgetStatisticModel $stat, Timesheet $timesheet, int $duration, float $rate, string $field): bool
|
||||
private function checkBudgets(TimesheetBudgetUsed $constraint, BudgetStatisticModel $stat, TimesheetEntity $timesheet, int $duration, float $rate, string $field): bool
|
||||
{
|
||||
$fullRate = ($stat->getBudgetSpent() + $rate);
|
||||
|
||||
@@ -203,7 +199,7 @@ final class TimesheetBudgetUsedValidator extends ConstraintValidator
|
||||
return false;
|
||||
}
|
||||
|
||||
private function addBudgetViolation(TimesheetBudgetUsed $constraint, Timesheet $timesheet, string $field, float $budget, float $rate): void
|
||||
private function addBudgetViolation(TimesheetBudgetUsed $constraint, TimesheetEntity $timesheet, string $field, float $budget, float $rate): void
|
||||
{
|
||||
// using the locale of the assigned user is not the best solution, but allows to be independent of the request stack
|
||||
$helper = new LocaleFormatter($this->localeService, $timesheet->getUser()?->getLocale() ?? 'en');
|
||||
|
||||
@@ -17,29 +17,25 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetExportedValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private Security $security)
|
||||
public function __construct(private readonly Security $security)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetExported)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetExported::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
if ($timesheet->getId() === null) {
|
||||
if ($value->getId() === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$timesheet->isExported()) {
|
||||
if (!$value->isExported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +43,7 @@ final class TimesheetExportedValidator extends ConstraintValidator
|
||||
// can trigger is right when the "export" flag ist set from the "edit form".
|
||||
// most teamleads should not have "edit_exported_timesheet" but only "edit_export_other_timesheet"
|
||||
|
||||
if (null !== $this->security->getUser() && $this->security->isGranted('edit_export', $timesheet)) {
|
||||
if (null !== $this->security->getUser() && $this->security->isGranted('edit_export', $value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,10 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetFutureTimesValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private SystemConfiguration $configuration)
|
||||
public function __construct(private readonly SystemConfiguration $configuration)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $value
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetFutureTimes)) {
|
||||
|
||||
@@ -18,29 +18,28 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetLockdownValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private Security $security, private LockdownService $lockdownService)
|
||||
public function __construct(
|
||||
private readonly Security $security,
|
||||
private readonly LockdownService $lockdownService
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetLockdown)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetLockdown::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
if (!$this->lockdownService->isLockdownActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === ($timesheetStart = $timesheet->getBegin())) {
|
||||
if (null === ($timesheetStart = $value->getBegin())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,7 +66,7 @@ final class TimesheetLockdownValidator extends ConstraintValidator
|
||||
$allowEditInGracePeriod = true;
|
||||
}
|
||||
|
||||
if ($this->lockdownService->isEditable($timesheet, $now, $allowEditInGracePeriod)) {
|
||||
if ($this->lockdownService->isEditable($value, $now, $allowEditInGracePeriod)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,30 +17,26 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetLongRunningValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private SystemConfiguration $systemConfiguration)
|
||||
public function __construct(private readonly SystemConfiguration $systemConfiguration)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetLongRunning)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetLongRunning::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
if ($timesheet->isRunning()) {
|
||||
if ($value->isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var int $duration */
|
||||
$duration = $timesheet->getCalculatedDuration();
|
||||
$duration = $value->getCalculatedDuration();
|
||||
|
||||
// one year is currently the maximum that can be logged (which is already not logically)
|
||||
// the database column could hold more data, but let's limit it here
|
||||
|
||||
@@ -18,26 +18,25 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetOverlappingValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private SystemConfiguration $configuration, private TimesheetRepository $repository)
|
||||
public function __construct(
|
||||
private readonly SystemConfiguration $configuration,
|
||||
private readonly TimesheetRepository $repository
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetOverlapping)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetOverlapping::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
$begin = $timesheet->getBegin();
|
||||
$end = $timesheet->getEnd();
|
||||
$begin = $value->getBegin();
|
||||
$end = $value->getEnd();
|
||||
|
||||
// this case is handled in TimesheetValidator and should not raise a second validation
|
||||
if ($begin !== null && $end !== null && $begin > $end) {
|
||||
@@ -48,7 +47,7 @@ final class TimesheetOverlappingValidator extends ConstraintValidator
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->repository->hasRecordForTime($timesheet)) {
|
||||
if (!$this->repository->hasRecordForTime($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,28 +18,27 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetRestartValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private Security $security, private TrackingModeService $trackingModeService)
|
||||
public function __construct(
|
||||
private readonly Security $security,
|
||||
private readonly TrackingModeService $trackingModeService
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetRestart)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetRestart::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
// special case that would otherwise need to be validated in several controllers:
|
||||
// an entry is edited and the end date is removed (or duration deleted) would restart the record,
|
||||
// which might be disallowed for the current user
|
||||
if (null !== $timesheet->getEnd()) {
|
||||
if (null !== $value->getEnd()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,7 +46,7 @@ final class TimesheetRestartValidator extends ConstraintValidator
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== $this->security->getUser() && $this->security->isGranted('start', $timesheet)) {
|
||||
if (null !== $this->security->getUser() && $this->security->isGranted('start', $value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,14 @@ final class TimesheetValidator extends ConstraintValidator
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetEntityConstraint)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetEntityConstraint::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
$groups = [Constraint::DEFAULT_GROUP];
|
||||
@@ -51,7 +47,7 @@ final class TimesheetValidator extends ConstraintValidator
|
||||
$this->context
|
||||
->getValidator()
|
||||
->inContext($this->context)
|
||||
->validate($timesheet, $innerConstraint, $groups);
|
||||
->validate($value, $innerConstraint, $groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,35 +17,31 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
final class TimesheetZeroDurationValidator extends ConstraintValidator
|
||||
{
|
||||
public function __construct(private SystemConfiguration $configuration)
|
||||
public function __construct(private readonly SystemConfiguration $configuration)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TimesheetEntity $timesheet
|
||||
* @param Constraint $constraint
|
||||
*/
|
||||
public function validate(mixed $timesheet, Constraint $constraint): void
|
||||
public function validate(mixed $value, Constraint $constraint): void
|
||||
{
|
||||
if (!($constraint instanceof TimesheetZeroDuration)) {
|
||||
throw new UnexpectedTypeException($constraint, TimesheetZeroDuration::class);
|
||||
}
|
||||
|
||||
if (!\is_object($timesheet) || !($timesheet instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($timesheet, TimesheetEntity::class);
|
||||
if (!\is_object($value) || !($value instanceof TimesheetEntity)) {
|
||||
throw new UnexpectedTypeException($value, TimesheetEntity::class);
|
||||
}
|
||||
|
||||
if ($this->configuration->isTimesheetAllowZeroDuration()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($timesheet->isRunning()) {
|
||||
if ($value->isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$duration = 0;
|
||||
if ($timesheet->getEnd() !== null && $timesheet->getBegin() !== null) {
|
||||
$duration = $timesheet->getCalculatedDuration();
|
||||
if ($value->getEnd() !== null && $value->getBegin() !== null) {
|
||||
$duration = $value->getCalculatedDuration();
|
||||
}
|
||||
|
||||
if ($duration <= 0) {
|
||||
|
||||
Reference in New Issue
Block a user