/**
  * {@inheritdoc}
  */
 public function addFieldFilter($field, $operator, $value, $locale = null, $scope = null, $options = [])
 {
     if (Operators::IS_EMPTY !== $operator && Operators::IS_NOT_EMPTY !== $operator && Operators::SINCE_LAST_JOB !== $operator && Operators::SINCE_LAST_N_DAYS !== $operator) {
         $value = $this->formatValues($field, $value);
     }
     if (Operators::SINCE_LAST_JOB === $operator) {
         if (!is_string($value)) {
             throw InvalidArgumentException::stringExpected($field, 'filter', 'updated', gettype($value));
         }
         $jobInstance = $this->jobInstanceRepository->findOneBy(['code' => $value]);
         $lastCompletedJobExecution = $this->jobRepository->getLastJobExecution($jobInstance, BatchStatus::COMPLETED);
         if (null === $lastCompletedJobExecution) {
             return $this;
         }
         $lastJobStartTime = $lastCompletedJobExecution->getStartTime()->setTimezone(new \DateTimeZone('UTC'));
         $value = $lastJobStartTime->getTimestamp();
         $operator = Operators::GREATER_THAN;
     }
     if (Operators::SINCE_LAST_N_DAYS === $operator) {
         if (!is_numeric($value)) {
             throw InvalidArgumentException::numericExpected($field, 'filter', 'updated', gettype($value));
         }
         $fromDate = new \DateTime(sprintf('%s days ago', $value), new \DateTimeZone('UTC'));
         $value = $fromDate->getTimestamp();
         $operator = Operators::GREATER_THAN;
     }
     $field = sprintf('%s.%s', ProductQueryUtility::NORMALIZED_FIELD, $field);
     $this->applyFilter($field, $operator, $value);
     return $this;
 }
 /**
  * Create a jobExecution
  *
  * @param JobInstance   $jobInstance
  * @param UserInterface $user
  *
  * @return JobExecution
  */
 protected function createJobExecution(JobInstance $jobInstance, UserInterface $user)
 {
     $jobExecution = $this->jobRepository->createJobExecution($jobInstance);
     $jobExecution->setUser($user->getUsername());
     $this->jobRepository->updateJobExecution($jobExecution);
     return $jobExecution;
 }
 /**
  * Create a jobExecution
  *
  * @param JobInstance   $jobInstance
  * @param UserInterface $user
  *
  * @return JobExecution
  */
 protected function createJobExecution(JobInstance $jobInstance, UserInterface $user)
 {
     $job = $this->jobRegistry->get($jobInstance->getJobName());
     $jobParameters = $this->jobParametersFactory->create($job, $jobInstance->getRawParameters());
     $jobExecution = $this->jobRepository->createJobExecution($jobInstance, $jobParameters);
     $jobExecution->setUser($user->getUsername());
     $this->jobRepository->updateJobExecution($jobExecution);
     return $jobExecution;
 }
 /**
  * Add a filter for products updated since the last export to the query builder
  *
  * @param string $field
  * @param string $value
  */
 protected function addUpdatedSinceLastJob($field, $value)
 {
     $jobInstance = $this->jobInstanceRepository->findOneBy(['code' => $value]);
     $lastCompletedJobExecution = $this->jobRepository->getLastJobExecution($jobInstance, BatchStatus::COMPLETED);
     if (null === $lastCompletedJobExecution) {
         return;
     }
     $lastJobStartTime = $lastCompletedJobExecution->getStartTime();
     $lastJobStartTime->setTimezone(new \DateTimeZone('UTC'));
     $updatedField = current($this->qb->getRootAliases()) . '.' . $field;
     $this->applyGreaterThanFilter($updatedField, $lastJobStartTime->format(static::DATETIME_FORMAT));
 }
 /**
  * Template method for step execution logic
  *
  * @param StepExecution $stepExecution
  *
  * @throws JobInterruptedException
  */
 public final function execute(StepExecution $stepExecution)
 {
     $this->dispatchStepExecutionEvent(EventInterface::BEFORE_STEP_EXECUTION, $stepExecution);
     $stepExecution->setStartTime(new \DateTime());
     $stepExecution->setStatus(new BatchStatus(BatchStatus::STARTED));
     $this->jobRepository->updateStepExecution($stepExecution);
     // Start with a default value that will be trumped by anything
     $exitStatus = new ExitStatus(ExitStatus::EXECUTING);
     try {
         $this->doExecute($stepExecution);
         $exitStatus = new ExitStatus(ExitStatus::COMPLETED);
         $exitStatus->logicalAnd($stepExecution->getExitStatus());
         $this->jobRepository->updateStepExecution($stepExecution);
         // Check if someone is trying to stop us
         if ($stepExecution->isTerminateOnly()) {
             throw new JobInterruptedException("JobExecution interrupted.");
         }
         // Need to upgrade here not set, in case the execution was stopped
         $stepExecution->upgradeStatus(BatchStatus::COMPLETED);
         $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_SUCCEEDED, $stepExecution);
     } catch (\Exception $e) {
         $stepExecution->upgradeStatus($this->determineBatchStatus($e));
         $exitStatus = $exitStatus->logicalAnd($this->getDefaultExitStatusForFailure($e));
         $stepExecution->addFailureException($e);
         $this->jobRepository->updateStepExecution($stepExecution);
         if ($stepExecution->getStatus()->getValue() == BatchStatus::STOPPED) {
             $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_INTERRUPTED, $stepExecution);
         } else {
             $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_ERRORED, $stepExecution);
         }
     }
     $this->dispatchStepExecutionEvent(EventInterface::STEP_EXECUTION_COMPLETED, $stepExecution);
     $stepExecution->setEndTime(new \DateTime());
     $stepExecution->setExitStatus($exitStatus);
     $this->jobRepository->updateStepExecution($stepExecution);
 }